diff -u -r -N xemacs-21.4.14/ChangeLog xemacs-21.4.15/ChangeLog --- xemacs-21.4.14/ChangeLog 2003-09-03 22:39:42.000000000 -0400 +++ xemacs-21.4.15/ChangeLog 2004-02-02 22:01:42.000000000 -0500 @@ -1,3 +1,79 @@ +2004-02-02 Vin Shelton + + * XEmacs 21.4.15 is released + +2004-01-30 Vin Shelton + + * etc/OXYMORONS: Inserted "Corporate Culture" for 21.4.15. + +2004-01-25 Steve Youngs + + * etc/package-index.LATEST.gpg: New, replaces + `package-index.LATEST.pgp'. + + * etc/package-index.LATEST.pgp: Removed, replaced with + `package-index.LATEST.gpg'. + +2004-01-20 Jerry James + + * configure.in: The icc compiler pretends to be gcc. It isn't. + +2003-11-28 Norbert Koch + + * etc/PACKAGES (ERC): new. + +2003-11-19 Vin Shelton + + * configure.usage (--with-widgets): widgets now defaults to + --with-widgets=no. Patch inspired by Jim Schumacher. + +2003-10-25 Norbert Koch + + * etc/PACKAGES (riece): New package. + * etc/PACKAGES (liece): Mark as deprecated. + +2003-10-26 Vin Shelton + + * configure.in: Add Intel C++ compiler detection to compiler + version reporting. + +2003-10-16 Valdis Kletnieks + * configure.in: record additional info about compiler and libc + versions, to assist in debugging. + +2003-08-28 Stephen J. Turnbull + + * configure.in (line 3573): + (Mule input methods): + Deprecate Motif for Linux. + (Installation): Report when LessTif is used. + +2003-10-11 Jerry James + + * configure.in: installexe.sh is under srcdir, not blddir. + +2003-10-16 Jerry James + * aclocal.m4: Add icc (Intel compiler) support. + * configure.in: Ditto. + +2003-09-13 Martin Buchholz + + * configure.in (OS_RELEASE): Add support for SunOS 5.10. + On current OSes produced by Sun, `uname -r' prints "5.9". + It seems likely that on future OSes, `uname -r' will print "5.10". + We need to accept multi-digit release numbers. + +2003-09-12 Rodney Sparapani + + * PROBLEMS: Propose bash as an alternative to buggy Solaris + /bin/sh. + +2003-09-10 Martin Buchholz + + * configure.in: XEmacs failed to build on Solaris9. + Solaris9 comes with /usr/demo/SOUND, but no headers or libraries + therein. + 2003-09-03 Vin Shelton * XEmacs 21.4.14 is released diff -u -r -N xemacs-21.4.14/PROBLEMS xemacs-21.4.15/PROBLEMS --- xemacs-21.4.14/PROBLEMS 2003-08-14 19:45:56.000000000 -0400 +++ xemacs-21.4.15/PROBLEMS 2003-09-13 21:44:32.000000000 -0400 @@ -445,7 +445,14 @@ This only occurs if you have LANG != C. This is a known bug with /bin/sh fixed by installing Patch-ID# 101613-01. Or, you can use -bash, as a workaround. +bash by setting the environment variable CONFIG_SHELL to /bin/bash + +*** Solaris 2.x configure fails: ./config.status: test: argument expected + +This is a known bug with /bin/sh and /bin/test, i.e. they do not +support the XPG4 standard. You can use bash as a workaround or an +XPG4-compliant Bourne shell such as the Sun-supplied /usr/xpg4/bin/sh +by setting the environment variable CONFIG_SHELL to /usr/xpg4/bin/sh *** On SunOS, you get linker errors ld: Undefined symbol diff -u -r -N xemacs-21.4.14/aclocal.m4 xemacs-21.4.15/aclocal.m4 --- xemacs-21.4.14/aclocal.m4 2001-07-25 03:39:21.000000000 -0400 +++ xemacs-21.4.15/aclocal.m4 2003-10-20 20:22:56.000000000 -0400 @@ -84,7 +84,7 @@ wl= can_build_shared=yes -if test "$XEGCC" = yes; then +if test "$XEGCC" = yes -o "$__ICC" = yes; then wl='-Wl,' case "$xehost_os" in @@ -243,7 +243,7 @@ xldf= xcldf= AC_MSG_CHECKING(if C compiler can produce shared libraries) -if test "$XEGCC" = yes; then +if test "$XEGCC" = yes -o "$__ICC" = yes; then xcldf="-shared" xldf="-shared" else # Not using GCC diff -u -r -N xemacs-21.4.14/configure xemacs-21.4.15/configure --- xemacs-21.4.14/configure 2003-08-17 21:43:10.000000000 -0400 +++ xemacs-21.4.15/configure 2004-01-23 23:34:33.000000000 -0500 @@ -1423,9 +1423,14 @@ esac case "$canonical" in - *-solaris* ) + *-solaris* ) opsys=sol2 - os_release=`uname -r | sed -e 's/^\([0-9]\)\.\([0-9]\).*/\1\2/'` + os_release_major=`uname -r | sed -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/\1/'` + os_release_minor=`uname -r | sed -e 's/^\([0-9]\{1,\}\)\.\([0-9]\{1,\}\).*/\2/'` + case "$os_release_minor" in [0-9]) + os_release_minor="0${os_release_minor}";; + esac + os_release="${os_release_major}${os_release_minor}" { test "$extra_verbose" = "yes" && cat << EOF Defining OS_RELEASE = $os_release EOF @@ -1649,7 +1654,7 @@ # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1653: checking for $ac_word" >&5 +echo "configure:1658: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1676,7 +1681,7 @@ # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1680: checking for $ac_word" >&5 +echo "configure:1685: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1724,7 +1729,7 @@ # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1728: checking for $ac_word" >&5 +echo "configure:1733: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1753,7 +1758,7 @@ fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1757: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1762: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c xe_cppflags='$CPPFLAGS $c_switch_site $c_switch_machine $c_switch_system $c_switch_x_site $X_CFLAGS' @@ -1766,12 +1771,12 @@ cat > conftest.$ac_ext << EOF -#line 1770 "configure" +#line 1775 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1799,19 +1804,19 @@ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1803: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1808: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1808: checking whether we are using GNU C" >&5 +echo "configure:1813: checking whether we are using GNU C" >&5 cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1820: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1829,7 +1834,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1833: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1838: checking whether ${CC-cc} accepts -g" >&5 echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then @@ -1862,7 +1867,7 @@ # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1866: checking for $ac_word" >&5 +echo "configure:1871: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1889,7 +1894,7 @@ # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1893: checking for $ac_word" >&5 +echo "configure:1898: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1937,7 +1942,7 @@ # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1941: checking for $ac_word" >&5 +echo "configure:1946: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1966,7 +1971,7 @@ fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1970: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1975: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c xe_cppflags='$CPPFLAGS $c_switch_site $c_switch_machine $c_switch_system $c_switch_x_site $X_CFLAGS' @@ -1979,12 +1984,12 @@ cat > conftest.$ac_ext << EOF -#line 1983 "configure" +#line 1988 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:1988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -2012,19 +2017,19 @@ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:2016: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:2021: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:2021: checking whether we are using GNU C" >&5 +echo "configure:2026: checking whether we are using GNU C" >&5 cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2033: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -2042,7 +2047,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:2046: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:2051: checking whether ${CC-cc} accepts -g" >&5 echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then @@ -2075,7 +2080,7 @@ # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2079: checking for $ac_word" >&5 +echo "configure:2084: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2102,7 +2107,7 @@ # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2106: checking for $ac_word" >&5 +echo "configure:2111: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2150,7 +2155,7 @@ # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2154: checking for $ac_word" >&5 +echo "configure:2159: checking for $ac_word" >&5 if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2179,7 +2184,7 @@ fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:2183: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:2188: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c xe_cppflags='$CPPFLAGS $c_switch_site $c_switch_machine $c_switch_system $c_switch_x_site $X_CFLAGS' @@ -2192,12 +2197,12 @@ cat > conftest.$ac_ext << EOF -#line 2196 "configure" +#line 2201 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:2201: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -2225,19 +2230,19 @@ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:2229: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:2234: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:2234: checking whether we are using GNU C" >&5 +echo "configure:2239: checking whether we are using GNU C" >&5 cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -2255,7 +2260,7 @@ ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:2259: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:2264: checking whether ${CC-cc} accepts -g" >&5 echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then @@ -2292,7 +2297,7 @@ test -n "$NON_GNU_CPP" -a "$GCC" != "yes" -a -z "$CPP" && CPP="$NON_GNU_CPP" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2296: checking how to run the C preprocessor" >&5 +echo "configure:2301: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -2305,13 +2310,13 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2322,13 +2327,13 @@ rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2332: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2337: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2339,13 +2344,13 @@ rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2349: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2354: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -2371,9 +2376,9 @@ echo $ac_n "checking for AIX""... $ac_c" 1>&6 -echo "configure:2375: checking for AIX" >&5 +echo "configure:2380: checking for AIX" >&5 cat > conftest.$ac_ext <&6 -echo "configure:2404: checking for GNU libc" >&5 +echo "configure:2409: checking for GNU libc" >&5 cat > conftest.$ac_ext < int main() { @@ -2414,7 +2419,7 @@ ; return 0; } EOF -if { (eval echo configure:2418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2423: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_glibc=yes else @@ -2444,7 +2449,7 @@ EOF } - if test "$os_release" -ge 55; then + if test "$os_release" -ge 505; then { test "$extra_verbose" = "yes" && cat << \EOF Defining _XOPEN_SOURCE = 500 EOF @@ -2491,7 +2496,7 @@ esac cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:2516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then : else @@ -2514,9 +2521,11 @@ cat conftest.$ac_ext >&5 rm -fr conftest* case "$conftest_rc" in - 11) echo "You appear to be using the SunPro C compiler."; __SUNPRO_C=yes ;; - 12) echo "You appear to be using the DEC C compiler." ; __DECC=yes ;; - 13) echo "You appear to be using the SCO C compiler." ; __USLC__=yes ;; + 11) echo "You appear to be using the SunPro C compiler." ; __SUNPRO_C=yes ;; + 12) echo "You appear to be using the DEC C compiler." ; __DECC=yes ;; + 13) echo "You appear to be using the SCO C compiler." ; __USLC__=yes ;; + 14) echo "You appear to be using the Intel C++ compiler."; __ICC=yes + GCC=no ;; esac fi rm -fr conftest* @@ -2739,17 +2748,17 @@ if test "$__USLC__" = yes; then echo $ac_n "checking for whether the -Kalloca compiler flag is needed""... $ac_c" 1>&6 -echo "configure:2743: checking for whether the -Kalloca compiler flag is needed" >&5 +echo "configure:2752: checking for whether the -Kalloca compiler flag is needed" >&5 need_kalloca=no cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2762: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* : else @@ -2760,14 +2769,14 @@ xe_save_c_switch_system="$c_switch_system" c_switch_system="$c_switch_system -Kalloca" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* need_kalloca=yes else @@ -2802,13 +2811,15 @@ CFLAGS="-O3" elif test "$CC" = "xlc"; then CFLAGS="-g -O3 -qstrict -qnoansialias -qlibansi -qinfo -qro -qmaxmem=20000" + elif test "$__ICC" = "yes"; then + CFLAGS="-g -O3 -Ob2 -Wall -W1" else CFLAGS="-O" ; fi fi if test "$GCC" = "yes"; then echo $ac_n "checking for buggy gcc versions""... $ac_c" 1>&6 -echo "configure:2812: checking for buggy gcc versions" >&5 +echo "configure:2823: checking for buggy gcc versions" >&5 GCC_VERSION=`$CC --version` case `uname -s`:`uname -m`:$GCC_VERSION in *:sun4*:2.8.1|*:sun4*:egcs-2.90.*) @@ -2866,7 +2877,7 @@ if test "$pdump" != "yes"; then echo $ac_n "checking for \"-z nocombreloc\" linker flag""... $ac_c" 1>&6 -echo "configure:2870: checking for \"-z nocombreloc\" linker flag" >&5 +echo "configure:2881: checking for \"-z nocombreloc\" linker flag" >&5 case "`ld --help 2>&1`" in *-z\ nocombreloc* ) echo "$ac_t""yes" 1>&6 ld_switch_site="-z nocombreloc $ld_switch_site" && if test "$extra_verbose" = "yes"; then echo " Prepending \"-z nocombreloc\" to \$ld_switch_site"; fi ;; @@ -2955,7 +2966,7 @@ fi echo $ac_n "checking for dynodump""... $ac_c" 1>&6 -echo "configure:2959: checking for dynodump" >&5 +echo "configure:2970: checking for dynodump" >&5 if test "$unexec" != "unexsol2.o"; then echo "$ac_t""no" 1>&6 else @@ -2993,12 +3004,12 @@ done echo $ac_n "checking for terminateAndUnload in -lC""... $ac_c" 1>&6 -echo "configure:2997: checking for terminateAndUnload in -lC" >&5 +echo "configure:3008: checking for terminateAndUnload in -lC" >&5 ac_lib_var=`echo C'_'terminateAndUnload | sed 'y%./+-%__p_%'` xe_check_libs=" -lC " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -3117,7 +3128,7 @@ if test "$add_runtime_path" = "yes"; then echo $ac_n "checking "for runtime libraries flag"""... $ac_c" 1>&6 -echo "configure:3121: checking "for runtime libraries flag"" >&5 +echo "configure:3132: checking "for runtime libraries flag"" >&5 case "$opsys" in sol2 ) dash_r="-R" ;; decosf* | linux* | irix*) dash_r="-rpath " ;; @@ -3139,14 +3150,14 @@ done fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3161: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* dash_r="$try_dash_r" else @@ -3213,7 +3224,7 @@ eval "$xe_add_unique_runpath_dir" };; esac done - if test "$opsys $need_motif" = "sol2 yes"; then + if test "$opsys $need_motif" = "sol2 yes"; then xe_runpath_dir="/opt/SUNWdt/lib"; eval "$xe_add_unique_runpath_dir"; fi @@ -3247,10 +3258,10 @@ fi after_morecore_hook_exists=yes echo $ac_n "checking for malloc_set_state""... $ac_c" 1>&6 -echo "configure:3251: checking for malloc_set_state" >&5 +echo "configure:3262: checking for malloc_set_state" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3288: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_malloc_set_state=yes" else @@ -3293,16 +3304,16 @@ fi echo $ac_n "checking whether __after_morecore_hook exists""... $ac_c" 1>&6 -echo "configure:3297: checking whether __after_morecore_hook exists" >&5 +echo "configure:3308: checking whether __after_morecore_hook exists" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else @@ -3358,7 +3369,7 @@ # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3362: checking for $ac_word" >&5 +echo "configure:3373: checking for $ac_word" >&5 if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. @@ -3413,7 +3424,7 @@ # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:3417: checking for a BSD compatible install" >&5 +echo "configure:3428: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" @@ -3467,7 +3478,7 @@ # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:3471: checking for $ac_word" >&5 +echo "configure:3482: checking for $ac_word" >&5 if test -n "$YACC"; then ac_cv_prog_YACC="$YACC" # Let the user override the test. @@ -3499,15 +3510,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:3503: checking for $ac_hdr" >&5 +echo "configure:3514: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3511: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3537,10 +3548,10 @@ done echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:3541: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo "configure:3552: checking for sys/wait.h that is POSIX.1 compatible" >&5 cat > conftest.$ac_ext < #include @@ -3556,7 +3567,7 @@ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF -if { (eval echo configure:3560: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3571: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else @@ -3580,10 +3591,10 @@ fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:3584: checking for ANSI C header files" >&5 +echo "configure:3595: checking for ANSI C header files" >&5 cat > conftest.$ac_ext < #include @@ -3591,7 +3602,7 @@ #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:3595: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:3606: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -3608,7 +3619,7 @@ if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3626,7 +3637,7 @@ if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -3644,7 +3655,7 @@ if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -3655,7 +3666,7 @@ exit (0); } EOF -if { (eval echo configure:3659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:3670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then : else @@ -3681,10 +3692,10 @@ fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:3685: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:3696: checking whether time.h and sys/time.h may both be included" >&5 cat > conftest.$ac_ext < #include @@ -3693,7 +3704,7 @@ struct tm *tp; ; return 0; } EOF -if { (eval echo configure:3697: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -3717,10 +3728,10 @@ fi echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6 -echo "configure:3721: checking for sys_siglist declaration in signal.h or unistd.h" >&5 +echo "configure:3732: checking for sys_siglist declaration in signal.h or unistd.h" >&5 cat > conftest.$ac_ext < #include @@ -3732,7 +3743,7 @@ char *msg = *(sys_siglist + 1); ; return 0; } EOF -if { (eval echo configure:3736: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3747: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_siglist=yes else @@ -3758,9 +3769,9 @@ echo $ac_n "checking for utime""... $ac_c" 1>&6 -echo "configure:3762: checking for utime" >&5 +echo "configure:3773: checking for utime" >&5 cat > conftest.$ac_ext < #include @@ -3768,7 +3779,7 @@ struct utimbuf x; x.actime = x.modtime = 0; utime ("/", &x); ; return 0; } EOF -if { (eval echo configure:3772: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3783: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 { test "$extra_verbose" = "yes" && cat << \EOF @@ -3787,10 +3798,10 @@ for ac_func in utimes do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3791: checking for $ac_func" >&5 +echo "configure:3802: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -3845,10 +3856,10 @@ echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:3849: checking return type of signal handlers" >&5 +echo "configure:3860: checking return type of signal handlers" >&5 cat > conftest.$ac_ext < #include @@ -3865,7 +3876,7 @@ int i; ; return 0; } EOF -if { (eval echo configure:3869: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:3880: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -3887,10 +3898,10 @@ echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:3891: checking for size_t" >&5 +echo "configure:3902: checking for size_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3921,10 +3932,10 @@ fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:3925: checking for pid_t" >&5 +echo "configure:3936: checking for pid_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -3955,10 +3966,10 @@ fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:3959: checking for uid_t in sys/types.h" >&5 +echo "configure:3970: checking for uid_t in sys/types.h" >&5 cat > conftest.$ac_ext < EOF @@ -3994,10 +4005,10 @@ fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 -echo "configure:3998: checking for mode_t" >&5 +echo "configure:4009: checking for mode_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -4028,10 +4039,10 @@ fi echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:4032: checking for off_t" >&5 +echo "configure:4043: checking for off_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -4062,10 +4073,10 @@ fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:4066: checking for ssize_t" >&5 +echo "configure:4077: checking for ssize_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -4097,9 +4108,9 @@ echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 -echo "configure:4101: checking for socklen_t" >&5 +echo "configure:4112: checking for socklen_t" >&5 cat > conftest.$ac_ext < #include @@ -4109,7 +4120,7 @@ ; return 0; } EOF -if { (eval echo configure:4113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4124: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else @@ -4118,7 +4129,7 @@ rm -rf conftest* cat > conftest.$ac_ext < #include @@ -4128,7 +4139,7 @@ ; return 0; } EOF -if { (eval echo configure:4132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4143: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""size_t" 1>&6 @@ -4160,9 +4171,9 @@ rm -f conftest* echo $ac_n "checking for struct timeval""... $ac_c" 1>&6 -echo "configure:4164: checking for struct timeval" >&5 +echo "configure:4175: checking for struct timeval" >&5 cat > conftest.$ac_ext < @@ -4178,7 +4189,7 @@ static struct timeval x; x.tv_sec = x.tv_usec; ; return 0; } EOF -if { (eval echo configure:4182: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 HAVE_TIMEVAL=yes @@ -4200,10 +4211,10 @@ rm -f conftest* echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 -echo "configure:4204: checking whether struct tm is in sys/time.h or time.h" >&5 +echo "configure:4215: checking whether struct tm is in sys/time.h or time.h" >&5 cat > conftest.$ac_ext < #include @@ -4211,7 +4222,7 @@ struct tm *tp; tp->tm_sec; ; return 0; } EOF -if { (eval echo configure:4215: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else @@ -4235,10 +4246,10 @@ fi echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6 -echo "configure:4239: checking for tm_zone in struct tm" >&5 +echo "configure:4250: checking for tm_zone in struct tm" >&5 cat > conftest.$ac_ext < #include <$ac_cv_struct_tm> @@ -4246,7 +4257,7 @@ struct tm tm; tm.tm_zone; ; return 0; } EOF -if { (eval echo configure:4250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4261: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm_zone=yes else @@ -4269,10 +4280,10 @@ else echo $ac_n "checking for tzname""... $ac_c" 1>&6 -echo "configure:4273: checking for tzname" >&5 +echo "configure:4284: checking for tzname" >&5 cat > conftest.$ac_ext < #ifndef tzname /* For SGI. */ @@ -4282,7 +4293,7 @@ atoi(*tzname); ; return 0; } EOF -if { (eval echo configure:4286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_var_tzname=yes else @@ -4308,10 +4319,10 @@ echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:4312: checking for working const" >&5 +echo "configure:4323: checking for working const" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4375: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -4385,7 +4396,7 @@ echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:4389: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:4400: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` cat > conftestmake <<\EOF @@ -4410,12 +4421,12 @@ echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:4414: checking whether byte ordering is bigendian" >&5 +echo "configure:4425: checking whether byte ordering is bigendian" >&5 ac_cv_c_bigendian=unknown # See if sys/param.h defines the BYTE_ORDER macro. cat > conftest.$ac_ext < #include @@ -4426,11 +4437,11 @@ #endif ; return 0; } EOF -if { (eval echo configure:4430: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4441: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # It does; now see whether it defined to BIG_ENDIAN or not. cat > conftest.$ac_ext < #include @@ -4441,7 +4452,7 @@ #endif ; return 0; } EOF -if { (eval echo configure:4445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4456: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_bigendian=yes else @@ -4458,7 +4469,7 @@ rm -f conftest* if test $ac_cv_c_bigendian = unknown; then cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_c_bigendian=no else @@ -4498,10 +4509,10 @@ echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:4502: checking size of short" >&5 +echo "configure:4513: checking size of short" >&5 cat > conftest.$ac_ext < main() @@ -4512,7 +4523,7 @@ exit(0); } EOF -if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_short=`cat conftestval` else @@ -4540,10 +4551,10 @@ exit 1 fi echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:4544: checking size of int" >&5 +echo "configure:4555: checking size of int" >&5 cat > conftest.$ac_ext < main() @@ -4554,7 +4565,7 @@ exit(0); } EOF -if { (eval echo configure:4558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_int=`cat conftestval` else @@ -4576,10 +4587,10 @@ echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:4580: checking size of long" >&5 +echo "configure:4591: checking size of long" >&5 cat > conftest.$ac_ext < main() @@ -4590,7 +4601,7 @@ exit(0); } EOF -if { (eval echo configure:4594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_long=`cat conftestval` else @@ -4612,10 +4623,10 @@ echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:4616: checking size of long long" >&5 +echo "configure:4627: checking size of long long" >&5 cat > conftest.$ac_ext < main() @@ -4626,7 +4637,7 @@ exit(0); } EOF -if { (eval echo configure:4630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_long_long=`cat conftestval` else @@ -4648,10 +4659,10 @@ echo $ac_n "checking size of void *""... $ac_c" 1>&6 -echo "configure:4652: checking size of void *" >&5 +echo "configure:4663: checking size of void *" >&5 cat > conftest.$ac_ext < main() @@ -4662,7 +4673,7 @@ exit(0); } EOF -if { (eval echo configure:4666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:4677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_void_p=`cat conftestval` else @@ -4686,7 +4697,7 @@ case $opsys in cygwin* ) cat > conftest.$ac_ext < EOF @@ -4711,7 +4722,7 @@ esac echo $ac_n "checking for long file names""... $ac_c" 1>&6 -echo "configure:4715: checking for long file names" >&5 +echo "configure:4726: checking for long file names" >&5 ac_cv_sys_long_file_names=yes # Test for long file names in all the places we know might matter: @@ -4757,10 +4768,10 @@ echo $ac_n "checking for sin""... $ac_c" 1>&6 -echo "configure:4761: checking for sin" >&5 +echo "configure:4772: checking for sin" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sin=yes" else @@ -4801,12 +4812,12 @@ echo "$ac_t""no" 1>&6 echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6 -echo "configure:4805: checking for sin in -lm" >&5 +echo "configure:4816: checking for sin in -lm" >&5 ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'` xe_check_libs=" -lm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -4861,14 +4872,14 @@ cat > conftest.$ac_ext < int main() { return atanh(1.0) + asinh(1.0) + acosh(1.0); ; return 0; } EOF -if { (eval echo configure:4872: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_INVERSE_HYPERBOLIC @@ -4885,14 +4896,14 @@ rm -f conftest* echo "checking type of mail spool file locking" 1>&6 -echo "configure:4889: checking type of mail spool file locking" >&5 +echo "configure:4900: checking type of mail spool file locking" >&5 for ac_func in lockf flock do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:4893: checking for $ac_func" >&5 +echo "configure:4904: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -4997,12 +5008,12 @@ case "$opsys" in decosf*) echo $ac_n "checking for cma_open in -lpthreads""... $ac_c" 1>&6 -echo "configure:5001: checking for cma_open in -lpthreads" >&5 +echo "configure:5012: checking for cma_open in -lpthreads" >&5 ac_lib_var=`echo pthreads'_'cma_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lpthreads " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5050,7 +5061,7 @@ echo $ac_n "checking whether the -xildoff compiler flag is required""... $ac_c" 1>&6 -echo "configure:5054: checking whether the -xildoff compiler flag is required" >&5 +echo "configure:5065: checking whether the -xildoff compiler flag is required" >&5 if ${CC-cc} '-###' -xildon no_such_file.c 2>&1 | grep '^[^ ]*/ild ' > /dev/null ; then if ${CC-cc} '-###' -xildoff no_such_file.c 2>&1 | grep '^[^ ]*/ild ' > /dev/null ; then echo "$ac_t""no" 1>&6; @@ -5060,9 +5071,9 @@ fi if test "$opsys" = "sol2"; then - if test "$os_release" -ge 56; then + if test "$os_release" -ge 506; then echo $ac_n "checking for \"-z ignore\" linker flag""... $ac_c" 1>&6 -echo "configure:5066: checking for \"-z ignore\" linker flag" >&5 +echo "configure:5077: checking for \"-z ignore\" linker flag" >&5 case "`ld -h 2>&1`" in *-z\ ignore\|record* ) echo "$ac_t""yes" 1>&6 ld_switch_site="-z ignore $ld_switch_site" && if test "$extra_verbose" = "yes"; then echo " Prepending \"-z ignore\" to \$ld_switch_site"; fi ;; @@ -5073,7 +5084,7 @@ echo "checking "for specified window system"" 1>&6 -echo "configure:5077: checking "for specified window system"" >&5 +echo "configure:5088: checking "for specified window system"" >&5 GNOME_CONFIG=no @@ -5081,7 +5092,7 @@ if test "$with_gnome" != "no"; then echo $ac_n "checking for GNOME configuration script""... $ac_c" 1>&6 -echo "configure:5085: checking for GNOME configuration script" >&5 +echo "configure:5096: checking for GNOME configuration script" >&5 for possible in gnome-config do possible_version=`${possible} --version 2> /dev/null` @@ -5112,7 +5123,7 @@ if test "$with_gtk" != "no";then echo $ac_n "checking for GTK configuration script""... $ac_c" 1>&6 -echo "configure:5116: checking for GTK configuration script" >&5 +echo "configure:5127: checking for GTK configuration script" >&5 for possible in gtk12-config gtk14-config gtk-config do possible_version=`${possible} --version 2> /dev/null` @@ -5134,18 +5145,18 @@ if test "${GTK_CONFIG}" != "no"; then echo $ac_n "checking gtk version""... $ac_c" 1>&6 -echo "configure:5138: checking gtk version" >&5 +echo "configure:5149: checking gtk version" >&5 GTK_VERSION=`${GTK_CONFIG} --version` echo "$ac_t""${GTK_VERSION}" 1>&6 echo $ac_n "checking gtk libs""... $ac_c" 1>&6 -echo "configure:5143: checking gtk libs" >&5 +echo "configure:5154: checking gtk libs" >&5 GTK_LIBS=`${GTK_CONFIG} --libs` libs_gtk="$libs_gtk ${GTK_LIBS}" && if test "$extra_verbose" = "yes"; then echo " Appending \"${GTK_LIBS}\" to \$libs_gtk"; fi echo "$ac_t""${GTK_LIBS}" 1>&6 echo $ac_n "checking gtk cflags""... $ac_c" 1>&6 -echo "configure:5149: checking gtk cflags" >&5 +echo "configure:5160: checking gtk cflags" >&5 GTK_CFLAGS=`${GTK_CONFIG} --cflags` if test "$GCC" = "yes"; then GTK_CFLAGS="${GTK_CFLAGS} -Wno-shadow" @@ -5155,19 +5166,19 @@ echo $ac_n "checking for main in -lgdk_imlib""... $ac_c" 1>&6 -echo "configure:5159: checking for main in -lgdk_imlib" >&5 +echo "configure:5170: checking for main in -lgdk_imlib" >&5 ac_lib_var=`echo gdk_imlib'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lgdk_imlib " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5189,12 +5200,12 @@ echo $ac_n "checking for Imlib_init in -lImlib""... $ac_c" 1>&6 -echo "configure:5193: checking for Imlib_init in -lImlib" >&5 +echo "configure:5204: checking for Imlib_init in -lImlib" >&5 ac_lib_var=`echo Imlib'_'Imlib_init | sed 'y%./+-%__p_%'` xe_check_libs=" -lImlib " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5228,10 +5239,10 @@ for ac_func in gdk_imlib_init do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5232: checking for $ac_func" >&5 +echo "configure:5243: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5333,15 +5344,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5337: checking for $ac_hdr" >&5 +echo "configure:5348: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5356: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5372,19 +5383,19 @@ echo $ac_n "checking for main in -lxml""... $ac_c" 1>&6 -echo "configure:5376: checking for main in -lxml" >&5 +echo "configure:5387: checking for main in -lxml" >&5 ac_lib_var=`echo xml'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lxml " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5406,19 +5417,19 @@ echo $ac_n "checking for main in -lglade""... $ac_c" 1>&6 -echo "configure:5410: checking for main in -lglade" >&5 +echo "configure:5421: checking for main in -lglade" >&5 ac_lib_var=`echo glade'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lglade " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5440,19 +5451,19 @@ echo $ac_n "checking for main in -lglade-gnome""... $ac_c" 1>&6 -echo "configure:5444: checking for main in -lglade-gnome" >&5 +echo "configure:5455: checking for main in -lglade-gnome" >&5 ac_lib_var=`echo glade-gnome'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lglade-gnome " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5473,7 +5484,7 @@ cat > conftest.$ac_ext < EOF @@ -5532,7 +5543,7 @@ # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:5536: checking for X" >&5 +echo "configure:5547: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -5592,12 +5603,12 @@ # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5601: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5612: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5666,14 +5677,14 @@ ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -5782,17 +5793,17 @@ case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 -echo "configure:5786: checking whether -R must be followed by a space" >&5 +echo "configure:5797: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_nospace=yes else @@ -5808,14 +5819,14 @@ else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_space=yes else @@ -5851,12 +5862,12 @@ else echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 -echo "configure:5855: checking for dnet_ntoa in -ldnet" >&5 +echo "configure:5866: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` xe_check_libs=" -ldnet " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5891,12 +5902,12 @@ if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:5895: checking for dnet_ntoa in -ldnet_stub" >&5 +echo "configure:5906: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` xe_check_libs=" -ldnet_stub " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -5936,10 +5947,10 @@ # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:5940: checking for gethostbyname" >&5 +echo "configure:5951: checking for gethostbyname" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -5983,12 +5994,12 @@ if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:5987: checking for gethostbyname in -lnsl" >&5 +echo "configure:5998: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` xe_check_libs=" -lnsl " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6014: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6029,10 +6040,10 @@ # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:6033: checking for connect" >&5 +echo "configure:6044: checking for connect" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -6078,12 +6089,12 @@ xe_msg_checking="for connect in -lsocket" test -n "$X_EXTRA_LIBS" && xe_msg_checking="$xe_msg_checking using extra libs $X_EXTRA_LIBS" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:6082: checking "$xe_msg_checking"" >&5 +echo "configure:6093: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` xe_check_libs=" -lsocket $X_EXTRA_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6118,10 +6129,10 @@ # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 -echo "configure:6122: checking for remove" >&5 +echo "configure:6133: checking for remove" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6159: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_remove=yes" else @@ -6165,12 +6176,12 @@ if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 -echo "configure:6169: checking for remove in -lposix" >&5 +echo "configure:6180: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` xe_check_libs=" -lposix " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6196: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6205,10 +6216,10 @@ # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 -echo "configure:6209: checking for shmat" >&5 +echo "configure:6220: checking for shmat" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6246: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else @@ -6252,12 +6263,12 @@ if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 -echo "configure:6256: checking for shmat in -lipc" >&5 +echo "configure:6267: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` xe_check_libs=" -lipc " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6304,12 +6315,12 @@ xe_msg_checking="for IceConnectionNumber in -lICE" test -n "$X_EXTRA_LIBS" && xe_msg_checking="$xe_msg_checking using extra libs $X_EXTRA_LIBS" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:6308: checking "$xe_msg_checking"" >&5 +echo "configure:6319: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` xe_check_libs=" -lICE $X_EXTRA_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6335: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6366,15 +6377,15 @@ ac_safe=`echo "Xm/Xm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xm/Xm.h""... $ac_c" 1>&6 -echo "configure:6370: checking for Xm/Xm.h" >&5 +echo "configure:6381: checking for Xm/Xm.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6378: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6391,12 +6402,12 @@ echo "$ac_t""yes" 1>&6 echo $ac_n "checking for XmStringFree in -lXm""... $ac_c" 1>&6 -echo "configure:6395: checking for XmStringFree in -lXm" >&5 +echo "configure:6406: checking for XmStringFree in -lXm" >&5 ac_lib_var=`echo Xm'_'XmStringFree | sed 'y%./+-%__p_%'` xe_check_libs=" -lXm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6506,7 +6517,7 @@ eval "$xe_add_unique_runpath_dir" };; esac done - if test "$opsys $need_motif" = "sol2 yes"; then + if test "$opsys $need_motif" = "sol2 yes"; then xe_runpath_dir="/opt/SUNWdt/lib"; eval "$xe_add_unique_runpath_dir"; fi @@ -6559,7 +6570,7 @@ echo "checking for X defines extracted by xmkmf" 1>&6 -echo "configure:6563: checking for X defines extracted by xmkmf" >&5 +echo "configure:6574: checking for X defines extracted by xmkmf" >&5 rm -fr conftestdir if mkdir conftestdir; then cd conftestdir @@ -6608,15 +6619,15 @@ ac_safe=`echo "X11/Intrinsic.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Intrinsic.h""... $ac_c" 1>&6 -echo "configure:6612: checking for X11/Intrinsic.h" >&5 +echo "configure:6623: checking for X11/Intrinsic.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6620: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6631: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6640,12 +6651,12 @@ echo $ac_n "checking for XOpenDisplay in -lX11""... $ac_c" 1>&6 -echo "configure:6644: checking for XOpenDisplay in -lX11" >&5 +echo "configure:6655: checking for XOpenDisplay in -lX11" >&5 ac_lib_var=`echo X11'_'XOpenDisplay | sed 'y%./+-%__p_%'` xe_check_libs=" -lX11 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6681,12 +6692,12 @@ xe_msg_checking="for XGetFontProperty in -lX11" test -n "-b i486-linuxaout" && xe_msg_checking="$xe_msg_checking using extra libs -b i486-linuxaout" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:6685: checking "$xe_msg_checking"" >&5 +echo "configure:6696: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo X11'_'XGetFontProperty | sed 'y%./+-%__p_%'` xe_check_libs=" -lX11 -b i486-linuxaout" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6712: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6724,12 +6735,12 @@ echo $ac_n "checking for XShapeSelectInput in -lXext""... $ac_c" 1>&6 -echo "configure:6728: checking for XShapeSelectInput in -lXext" >&5 +echo "configure:6739: checking for XShapeSelectInput in -lXext" >&5 ac_lib_var=`echo Xext'_'XShapeSelectInput | sed 'y%./+-%__p_%'` xe_check_libs=" -lXext " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6763,12 +6774,12 @@ echo $ac_n "checking for XtOpenDisplay in -lXt""... $ac_c" 1>&6 -echo "configure:6767: checking for XtOpenDisplay in -lXt" >&5 +echo "configure:6778: checking for XtOpenDisplay in -lXt" >&5 ac_lib_var=`echo Xt'_'XtOpenDisplay | sed 'y%./+-%__p_%'` xe_check_libs=" -lXt " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6802,14 +6813,14 @@ echo $ac_n "checking the version of X11 being used""... $ac_c" 1>&6 -echo "configure:6806: checking the version of X11 being used" >&5 +echo "configure:6817: checking the version of X11 being used" >&5 cat > conftest.$ac_ext < int main(int c, char *v[]) { return c>1 ? XlibSpecificationRelease : 0; } EOF -if { (eval echo configure:6813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:6824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ./conftest foobar; x11_release=$? else @@ -6840,10 +6851,10 @@ for ac_func in XConvertCase do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6844: checking for $ac_func" >&5 +echo "configure:6855: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6898,15 +6909,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6902: checking for $ac_hdr" >&5 +echo "configure:6913: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6921: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6939,10 +6950,10 @@ for ac_func in XRegisterIMInstantiateCallback do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6943: checking for $ac_func" >&5 +echo "configure:6954: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6993,9 +7004,9 @@ done echo $ac_n "checking for standard XRegisterIMInstantiateCallback prototype""... $ac_c" 1>&6 -echo "configure:6997: checking for standard XRegisterIMInstantiateCallback prototype" >&5 +echo "configure:7008: checking for standard XRegisterIMInstantiateCallback prototype" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:7022: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else @@ -7028,12 +7039,12 @@ test -z "$with_xmu" && { echo $ac_n "checking for XmuReadBitmapDataFromFile in -lXmu""... $ac_c" 1>&6 -echo "configure:7032: checking for XmuReadBitmapDataFromFile in -lXmu" >&5 +echo "configure:7043: checking for XmuReadBitmapDataFromFile in -lXmu" >&5 ac_lib_var=`echo Xmu'_'XmuReadBitmapDataFromFile | sed 'y%./+-%__p_%'` xe_check_libs=" -lXmu " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7083,19 +7094,19 @@ echo $ac_n "checking for main in -lXbsd""... $ac_c" 1>&6 -echo "configure:7087: checking for main in -lXbsd" >&5 +echo "configure:7098: checking for main in -lXbsd" >&5 ac_lib_var=`echo Xbsd'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lXbsd " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7119,7 +7130,7 @@ if test "$unexec" = "unexaix.o" -a "$x11_release" = "6"; then if test "$GCC" = "yes"; then echo $ac_n "checking for name of AIX gcc threads option""... $ac_c" 1>&6 -echo "configure:7123: checking for name of AIX gcc threads option" >&5 +echo "configure:7134: checking for name of AIX gcc threads option" >&5 case `$CC -v --help 2>&1` in *-mthreads*) aix_threads=-mthreads ;; *) aix_threads=-pthread ;; @@ -7133,10 +7144,10 @@ xe_save_CC="$CC" CC="${CC}_r" echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:7137: checking size of short" >&5 +echo "configure:7148: checking size of short" >&5 cat > conftest.$ac_ext < main() @@ -7147,7 +7158,7 @@ exit(0); } EOF -if { (eval echo configure:7151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:7162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_sizeof_short=`cat conftestval` else @@ -7176,22 +7187,22 @@ fi if test "$with_msw" != "no"; then echo "checking for MS-Windows" 1>&6 -echo "configure:7180: checking for MS-Windows" >&5 +echo "configure:7191: checking for MS-Windows" >&5 echo $ac_n "checking for main in -lgdi32""... $ac_c" 1>&6 -echo "configure:7183: checking for main in -lgdi32" >&5 +echo "configure:7194: checking for main in -lgdi32" >&5 ac_lib_var=`echo gdi32'_'main | sed 'y%./+-%__p_%'` xe_check_libs=" -lgdi32 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7227,7 +7238,7 @@ INSTALL_ARCH_DEP_SUBDIR="$INSTALL_ARCH_DEP_SUBDIR netinstall" && if test "$extra_verbose" = "yes"; then echo " Appending \"netinstall\" to \$INSTALL_ARCH_DEP_SUBDIR"; fi fi - install_pp="$blddir/lib-src/installexe.sh" + install_pp="$srcdir/lib-src/installexe.sh" libs_system="$libs_system -lshell32 -lgdi32 -luser32 -lcomdlg32 -lcomctl32 -lkernel32 -lwinspool" && if test "$extra_verbose" = "yes"; then echo " Appending \"-lshell32 -lgdi32 -luser32 -lcomdlg32 -lcomctl32 -lkernel32 -lwinspool\" to \$libs_system"; fi test "$with_dragndrop" != no && dragndrop_proto="$dragndrop_proto msw" && if test "$extra_verbose" = "yes"; then echo " Appending \"msw\" to \$dragndrop_proto"; fi if test "$window_system" != x11; then @@ -7264,12 +7275,12 @@ fi fi cat > conftest.$ac_ext < int main() { return (open("/dev/windows", O_RDONLY, 0) > 0)? 0 : 1; } EOF -if { (eval echo configure:7273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:7284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then need_event_unixoid=yes; { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_MSG_SELECT @@ -7333,15 +7344,15 @@ if test "$with_x11" = "yes"; then ac_safe=`echo "X11/extensions/shape.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/extensions/shape.h""... $ac_c" 1>&6 -echo "configure:7337: checking for X11/extensions/shape.h" >&5 +echo "configure:7348: checking for X11/extensions/shape.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7345: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7356: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7393,7 +7404,7 @@ esac echo "checking for WM_COMMAND option" 1>&6 -echo "configure:7397: checking for WM_COMMAND option" >&5; +echo "configure:7408: checking for WM_COMMAND option" >&5; if test "$with_wmcommand" != "no"; then { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_WMCOMMAND @@ -7408,15 +7419,15 @@ test -z "$with_xauth" && test "$window_system" = "none" && with_xauth=no test -z "$with_xauth" && { ac_safe=`echo "X11/Xauth.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xauth.h""... $ac_c" 1>&6 -echo "configure:7412: checking for X11/Xauth.h" >&5 +echo "configure:7423: checking for X11/Xauth.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7431: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7439,12 +7450,12 @@ } test -z "$with_xauth" && { echo $ac_n "checking for XauGetAuthByAddr in -lXau""... $ac_c" 1>&6 -echo "configure:7443: checking for XauGetAuthByAddr in -lXau" >&5 +echo "configure:7454: checking for XauGetAuthByAddr in -lXau" >&5 ac_lib_var=`echo Xau'_'XauGetAuthByAddr | sed 'y%./+-%__p_%'` xe_check_libs=" -lXau " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7500,15 +7511,15 @@ for dir in "" "Tt/" "desktop/" ; do ac_safe=`echo "${dir}tt_c.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ${dir}tt_c.h""... $ac_c" 1>&6 -echo "configure:7504: checking for ${dir}tt_c.h" >&5 +echo "configure:7515: checking for ${dir}tt_c.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7512: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7523: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7544,12 +7555,12 @@ xe_msg_checking="for tt_message_create in -ltt" test -n "$extra_libs" && xe_msg_checking="$xe_msg_checking using extra libs $extra_libs" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:7548: checking "$xe_msg_checking"" >&5 +echo "configure:7559: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo tt'_'tt_message_create | sed 'y%./+-%__p_%'` xe_check_libs=" -ltt $extra_libs" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7617,15 +7628,15 @@ test -z "$with_cde" && { ac_safe=`echo "Dt/Dt.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Dt/Dt.h""... $ac_c" 1>&6 -echo "configure:7621: checking for Dt/Dt.h" >&5 +echo "configure:7632: checking for Dt/Dt.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7629: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7640: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7648,12 +7659,12 @@ } test -z "$with_cde" && { echo $ac_n "checking for DtDndDragStart in -lDtSvc""... $ac_c" 1>&6 -echo "configure:7652: checking for DtDndDragStart in -lDtSvc" >&5 +echo "configure:7663: checking for DtDndDragStart in -lDtSvc" >&5 ac_lib_var=`echo DtSvc'_'DtDndDragStart | sed 'y%./+-%__p_%'` xe_check_libs=" -lDtSvc " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7737,7 +7748,7 @@ if test "$with_dragndrop" != "no" ; then echo $ac_n "checking if drag and drop API is needed""... $ac_c" 1>&6 -echo "configure:7741: checking if drag and drop API is needed" >&5 +echo "configure:7752: checking if drag and drop API is needed" >&5 if test -n "$dragndrop_proto" ; then with_dragndrop=yes echo "$ac_t""yes (${dragndrop_proto} )" 1>&6 @@ -7757,18 +7768,18 @@ fi echo "checking for LDAP" 1>&6 -echo "configure:7761: checking for LDAP" >&5 +echo "configure:7772: checking for LDAP" >&5 test -z "$with_ldap" && { ac_safe=`echo "ldap.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ldap.h""... $ac_c" 1>&6 -echo "configure:7764: checking for ldap.h" >&5 +echo "configure:7775: checking for ldap.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7772: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7783: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7791,15 +7802,15 @@ } test -z "$with_ldap" && { ac_safe=`echo "lber.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for lber.h""... $ac_c" 1>&6 -echo "configure:7795: checking for lber.h" >&5 +echo "configure:7806: checking for lber.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:7803: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:7814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -7823,12 +7834,12 @@ if test "$with_ldap" != "no"; then echo $ac_n "checking for ldap_search in -lldap""... $ac_c" 1>&6 -echo "configure:7827: checking for ldap_search in -lldap" >&5 +echo "configure:7838: checking for ldap_search in -lldap" >&5 ac_lib_var=`echo ldap'_'ldap_search | sed 'y%./+-%__p_%'` xe_check_libs=" -lldap " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7864,12 +7875,12 @@ xe_msg_checking="for ldap_open in -lldap" test -n "-llber" && xe_msg_checking="$xe_msg_checking using extra libs -llber" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:7868: checking "$xe_msg_checking"" >&5 +echo "configure:7879: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo ldap'_'ldap_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lldap -llber" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7905,12 +7916,12 @@ xe_msg_checking="for ldap_open in -lldap" test -n "-llber -lkrb" && xe_msg_checking="$xe_msg_checking using extra libs -llber -lkrb" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:7909: checking "$xe_msg_checking"" >&5 +echo "configure:7920: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo ldap'_'ldap_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lldap -llber -lkrb" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -7946,12 +7957,12 @@ xe_msg_checking="for ldap_open in -lldap" test -n "-llber -lkrb -ldes" && xe_msg_checking="$xe_msg_checking using extra libs -llber -lkrb -ldes" echo $ac_n "checking "$xe_msg_checking"""... $ac_c" 1>&6 -echo "configure:7950: checking "$xe_msg_checking"" >&5 +echo "configure:7961: checking "$xe_msg_checking"" >&5 ac_lib_var=`echo ldap'_'ldap_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lldap -llber -lkrb -ldes" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8013,10 +8024,10 @@ for ac_func in ldap_set_option ldap_get_lderrno ldap_result2error ldap_parse_result do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:8017: checking for $ac_func" >&5 +echo "configure:8028: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -8070,20 +8081,20 @@ if test "$with_postgresql" != "no"; then echo "checking for PostgreSQL" 1>&6 -echo "configure:8074: checking for PostgreSQL" >&5 +echo "configure:8085: checking for PostgreSQL" >&5 for header_dir in "" "pgsql/" "postgresql/"; do ac_safe=`echo "${header_dir}libpq-fe.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ${header_dir}libpq-fe.h""... $ac_c" 1>&6 -echo "configure:8079: checking for ${header_dir}libpq-fe.h" >&5 +echo "configure:8090: checking for ${header_dir}libpq-fe.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8098: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8107,12 +8118,12 @@ test -n "$libpq_fe_h_file" && { echo $ac_n "checking for PQconnectdb in -lpq""... $ac_c" 1>&6 -echo "configure:8111: checking for PQconnectdb in -lpq" >&5 +echo "configure:8122: checking for PQconnectdb in -lpq" >&5 ac_lib_var=`echo pq'_'PQconnectdb | sed 'y%./+-%__p_%'` xe_check_libs=" -lpq " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8156,12 +8167,12 @@ echo $ac_n "checking for PQconnectStart in -lpq""... $ac_c" 1>&6 -echo "configure:8160: checking for PQconnectStart in -lpq" >&5 +echo "configure:8171: checking for PQconnectStart in -lpq" >&5 ac_lib_var=`echo pq'_'PQconnectStart | sed 'y%./+-%__p_%'` xe_check_libs=" -lpq " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8220,7 +8231,7 @@ if test "$window_system" != "none"; then echo "checking for graphics libraries" 1>&6 -echo "configure:8224: checking for graphics libraries" >&5 +echo "configure:8235: checking for graphics libraries" >&5 libpath_xpm= incpath_xpm= @@ -8246,10 +8257,10 @@ CFLAGS=""$incpath_xpm" $CFLAGS" && if test "$extra_verbose" = "yes"; then echo " Prepending \""$incpath_xpm"\" to \$CFLAGS"; fi LDFLAGS=""$libpath_xpm" $LDFLAGS" && if test "$extra_verbose" = "yes"; then echo " Prepending \""$libpath_xpm"\" to \$LDFLAGS"; fi echo $ac_n "checking for Xpm - no older than 3.4f""... $ac_c" 1>&6 -echo "configure:8250: checking for Xpm - no older than 3.4f" >&5 +echo "configure:8261: checking for Xpm - no older than 3.4f" >&5 xe_check_libs=-lXpm cat > conftest.$ac_ext < @@ -8258,7 +8269,7 @@ XpmIncludeVersion != XpmLibraryVersion() ? 1 : XpmIncludeVersion < 30406 ? 2 : 0 ;} EOF -if { (eval echo configure:8262: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:8273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ./conftest dummy_arg; xpm_status=$?; if test "$xpm_status" = "0"; then @@ -8302,17 +8313,17 @@ libs_x="-lXpm $libs_x" && if test "$extra_verbose" = "yes"; then echo " Prepending \"-lXpm\" to \$libs_x"; fi CFLAGS=""$incpath_xpm" $CFLAGS" && if test "$extra_verbose" = "yes"; then echo " Prepending \""$incpath_xpm"\" to \$CFLAGS"; fi echo $ac_n "checking for \"FOR_MSW\" xpm""... $ac_c" 1>&6 -echo "configure:8306: checking for \"FOR_MSW\" xpm" >&5 +echo "configure:8317: checking for \"FOR_MSW\" xpm" >&5 xe_check_libs=-lXpm cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* xpm_for_msw=no else @@ -8338,15 +8349,15 @@ test -z "$with_xface" && { ac_safe=`echo "compface.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for compface.h""... $ac_c" 1>&6 -echo "configure:8342: checking for compface.h" >&5 +echo "configure:8353: checking for compface.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8350: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8361: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8369,12 +8380,12 @@ } test -z "$with_xface" && { echo $ac_n "checking for UnGenFace in -lcompface""... $ac_c" 1>&6 -echo "configure:8373: checking for UnGenFace in -lcompface" >&5 +echo "configure:8384: checking for UnGenFace in -lcompface" >&5 ac_lib_var=`echo compface'_'UnGenFace | sed 'y%./+-%__p_%'` xe_check_libs=" -lcompface " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8437,12 +8448,12 @@ if test "$with_png $with_tiff" != "no no"; then echo $ac_n "checking for inflate in -lc""... $ac_c" 1>&6 -echo "configure:8441: checking for inflate in -lc" >&5 +echo "configure:8452: checking for inflate in -lc" >&5 ac_lib_var=`echo c'_'inflate | sed 'y%./+-%__p_%'` xe_check_libs=" -lc " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8472,12 +8483,12 @@ echo "$ac_t""no" 1>&6 echo $ac_n "checking for inflate in -lz""... $ac_c" 1>&6 -echo "configure:8476: checking for inflate in -lz" >&5 +echo "configure:8487: checking for inflate in -lz" >&5 ac_lib_var=`echo z'_'inflate | sed 'y%./+-%__p_%'` xe_check_libs=" -lz " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8507,12 +8518,12 @@ echo "$ac_t""no" 1>&6 echo $ac_n "checking for inflate in -lgz""... $ac_c" 1>&6 -echo "configure:8511: checking for inflate in -lgz" >&5 +echo "configure:8522: checking for inflate in -lgz" >&5 ac_lib_var=`echo gz'_'inflate | sed 'y%./+-%__p_%'` xe_check_libs=" -lgz " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8538: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8553,15 +8564,15 @@ test -z "$with_jpeg" && { ac_safe=`echo "jpeglib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for jpeglib.h""... $ac_c" 1>&6 -echo "configure:8557: checking for jpeglib.h" >&5 +echo "configure:8568: checking for jpeglib.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8565: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8576: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8584,12 +8595,12 @@ } test -z "$with_jpeg" && { echo $ac_n "checking for jpeg_destroy_decompress in -ljpeg""... $ac_c" 1>&6 -echo "configure:8588: checking for jpeg_destroy_decompress in -ljpeg" >&5 +echo "configure:8599: checking for jpeg_destroy_decompress in -ljpeg" >&5 ac_lib_var=`echo jpeg'_'jpeg_destroy_decompress | sed 'y%./+-%__p_%'` xe_check_libs=" -ljpeg " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8636,10 +8647,10 @@ png_problem="" test -z "$with_png" && { echo $ac_n "checking for pow""... $ac_c" 1>&6 -echo "configure:8640: checking for pow" >&5 +echo "configure:8651: checking for pow" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_pow=yes" else @@ -8683,15 +8694,15 @@ } test -z "$with_png" && { ac_safe=`echo "png.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for png.h""... $ac_c" 1>&6 -echo "configure:8687: checking for png.h" >&5 +echo "configure:8698: checking for png.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8695: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8706: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8714,12 +8725,12 @@ } test -z "$with_png" && { echo $ac_n "checking for png_read_image in -lpng""... $ac_c" 1>&6 -echo "configure:8718: checking for png_read_image in -lpng" >&5 +echo "configure:8729: checking for png_read_image in -lpng" >&5 ac_lib_var=`echo png'_'png_read_image | sed 'y%./+-%__p_%'` xe_check_libs=" -lpng " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8753,10 +8764,10 @@ } if test -z "$with_png"; then echo $ac_n "checking for workable png version information""... $ac_c" 1>&6 -echo "configure:8757: checking for workable png version information" >&5 +echo "configure:8768: checking for workable png version information" >&5 xe_check_libs="-lpng -lz" cat > conftest.$ac_ext < int main(int c, char **v) { @@ -8764,7 +8775,7 @@ if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING) != 0) return 1; return (PNG_LIBPNG_VER < 10002) ? 2 : 0 ;} EOF -if { (eval echo configure:8768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:8779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ./conftest dummy_arg; png_status=$?; if test "$png_status" = "0"; then @@ -8807,15 +8818,15 @@ test -z "$with_tiff" && { ac_safe=`echo "tiffio.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for tiffio.h""... $ac_c" 1>&6 -echo "configure:8811: checking for tiffio.h" >&5 +echo "configure:8822: checking for tiffio.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8819: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8830: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8838,12 +8849,12 @@ } test -z "$with_tiff" && { echo $ac_n "checking for TIFFClientOpen in -ltiff""... $ac_c" 1>&6 -echo "configure:8842: checking for TIFFClientOpen in -ltiff" >&5 +echo "configure:8853: checking for TIFFClientOpen in -ltiff" >&5 ac_lib_var=`echo tiff'_'TIFFClientOpen | sed 'y%./+-%__p_%'` xe_check_libs=" -ltiff " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8893,15 +8904,15 @@ if test "$with_gtk" = "yes"; then test -z "$with_xface" && { ac_safe=`echo "compface.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for compface.h""... $ac_c" 1>&6 -echo "configure:8897: checking for compface.h" >&5 +echo "configure:8908: checking for compface.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:8905: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:8916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -8924,12 +8935,12 @@ } test -z "$with_xface" && { echo $ac_n "checking for UnGenFace in -lcompface""... $ac_c" 1>&6 -echo "configure:8928: checking for UnGenFace in -lcompface" >&5 +echo "configure:8939: checking for UnGenFace in -lcompface" >&5 ac_lib_var=`echo compface'_'UnGenFace | sed 'y%./+-%__p_%'` xe_check_libs=" -lcompface " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:8955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -8979,12 +8990,12 @@ if test "$with_x11" = "yes"; then echo "checking for X11 graphics libraries" 1>&6 -echo "configure:8983: checking for X11 graphics libraries" >&5 +echo "configure:8994: checking for X11 graphics libraries" >&5 fi if test "$with_x11" = "yes"; then echo "checking for the Athena widgets" 1>&6 -echo "configure:8988: checking for the Athena widgets" >&5 +echo "configure:8999: checking for the Athena widgets" >&5 case "$with_athena" in "xaw" | "") athena_variant=Xaw athena_3d=no ;; @@ -9000,12 +9011,12 @@ if test "$athena_3d" = "no"; then echo $ac_n "checking for XawScrollbarSetThumb in -l$athena_variant""... $ac_c" 1>&6 -echo "configure:9004: checking for XawScrollbarSetThumb in -l$athena_variant" >&5 +echo "configure:9015: checking for XawScrollbarSetThumb in -l$athena_variant" >&5 ac_lib_var=`echo $athena_variant'_'XawScrollbarSetThumb | sed 'y%./+-%__p_%'` xe_check_libs=" -l$athena_variant " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9032,12 +9043,12 @@ echo "$ac_t""yes" 1>&6 echo $ac_n "checking for $athena_3d_function in -l$athena_variant""... $ac_c" 1>&6 -echo "configure:9036: checking for $athena_3d_function in -l$athena_variant" >&5 +echo "configure:9047: checking for $athena_3d_function in -l$athena_variant" >&5 ac_lib_var=`echo $athena_variant'_'$athena_3d_function | sed 'y%./+-%__p_%'` xe_check_libs=" -l$athena_variant " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9079,12 +9090,12 @@ else echo $ac_n "checking for $athena_3d_function in -l$athena_variant""... $ac_c" 1>&6 -echo "configure:9083: checking for $athena_3d_function in -l$athena_variant" >&5 +echo "configure:9094: checking for $athena_3d_function in -l$athena_variant" >&5 ac_lib_var=`echo $athena_variant'_'$athena_3d_function | sed 'y%./+-%__p_%'` xe_check_libs=" -l$athena_variant " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9113,12 +9124,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for $athena_3d_function in -lXaw""... $ac_c" 1>&6 -echo "configure:9117: checking for $athena_3d_function in -lXaw" >&5 +echo "configure:9128: checking for $athena_3d_function in -lXaw" >&5 ac_lib_var=`echo Xaw'_'$athena_3d_function | sed 'y%./+-%__p_%'` xe_check_libs=" -lXaw " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9160,15 +9171,15 @@ if test "$athena_3d" = "no"; then ac_safe=`echo "X11/Xaw/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xaw/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9164: checking for X11/Xaw/ThreeD.h" >&5 +echo "configure:9175: checking for X11/Xaw/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9188,15 +9199,15 @@ echo "$ac_t""no" 1>&6 ac_safe=`echo "X11/Xaw/XawInit.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xaw/XawInit.h""... $ac_c" 1>&6 -echo "configure:9192: checking for X11/Xaw/XawInit.h" >&5 +echo "configure:9203: checking for X11/Xaw/XawInit.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9211: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9222,15 +9233,15 @@ else ac_safe=`echo "X11/$athena_variant/XawInit.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/$athena_variant/XawInit.h""... $ac_c" 1>&6 -echo "configure:9226: checking for X11/$athena_variant/XawInit.h" >&5 +echo "configure:9237: checking for X11/$athena_variant/XawInit.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9234: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9245: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9247,15 +9258,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "X11/$athena_variant/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/$athena_variant/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9251: checking for X11/$athena_variant/ThreeD.h" >&5 +echo "configure:9262: checking for X11/$athena_variant/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9259: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9270: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9283,15 +9294,15 @@ if test -z "$athena_h_path"; then ac_safe=`echo "$athena_variant/XawInit.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $athena_variant/XawInit.h""... $ac_c" 1>&6 -echo "configure:9287: checking for $athena_variant/XawInit.h" >&5 +echo "configure:9298: checking for $athena_variant/XawInit.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9306: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9308,15 +9319,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "$athena_variant/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $athena_variant/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9312: checking for $athena_variant/ThreeD.h" >&5 +echo "configure:9323: checking for $athena_variant/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9320: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9331: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9345,15 +9356,15 @@ if test -z "$athena_h_path" -a "$athena_variant" != "Xaw3d"; then ac_safe=`echo "X11/Xaw3d/XawInit.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xaw3d/XawInit.h""... $ac_c" 1>&6 -echo "configure:9349: checking for X11/Xaw3d/XawInit.h" >&5 +echo "configure:9360: checking for X11/Xaw3d/XawInit.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9368: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9370,15 +9381,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "X11/Xaw3d/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xaw3d/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9374: checking for X11/Xaw3d/ThreeD.h" >&5 +echo "configure:9385: checking for X11/Xaw3d/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9382: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9410,15 +9421,15 @@ if test -z "$athena_h_path" -a "$athena_variant" != "Xaw3d"; then ac_safe=`echo "Xaw3d/XawInit.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xaw3d/XawInit.h""... $ac_c" 1>&6 -echo "configure:9414: checking for Xaw3d/XawInit.h" >&5 +echo "configure:9425: checking for Xaw3d/XawInit.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9422: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9435,15 +9446,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "Xaw3d/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xaw3d/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9439: checking for Xaw3d/ThreeD.h" >&5 +echo "configure:9450: checking for Xaw3d/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9447: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9458: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9475,15 +9486,15 @@ if test -z "$athena_h_path"; then ac_safe=`echo "X11/Xaw/ThreeD.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for X11/Xaw/ThreeD.h""... $ac_c" 1>&6 -echo "configure:9479: checking for X11/Xaw/ThreeD.h" >&5 +echo "configure:9490: checking for X11/Xaw/ThreeD.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9522,15 +9533,15 @@ if test "$with_x11" = "yes"; then ac_safe=`echo "Xm/Xm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for Xm/Xm.h""... $ac_c" 1>&6 -echo "configure:9526: checking for Xm/Xm.h" >&5 +echo "configure:9537: checking for Xm/Xm.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:9534: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:9545: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -9547,12 +9558,12 @@ echo "$ac_t""yes" 1>&6 echo $ac_n "checking for XmStringFree in -lXm""... $ac_c" 1>&6 -echo "configure:9551: checking for XmStringFree in -lXm" >&5 +echo "configure:9562: checking for XmStringFree in -lXm" >&5 ac_lib_var=`echo Xm'_'XmStringFree | sed 'y%./+-%__p_%'` xe_check_libs=" -lXm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:9578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9592,9 +9603,9 @@ if test "$have_motif" = "yes"; then echo $ac_n "checking for Lesstif""... $ac_c" 1>&6 -echo "configure:9596: checking for Lesstif" >&5 +echo "configure:9607: checking for Lesstif" >&5 cat > conftest.$ac_ext < #ifdef LESSTIF_VERSION @@ -9617,13 +9628,25 @@ fi +case "$opsys" in + *linux* ) lucid_prefers_motif = "no" ;; + * ) lucid_prefers_motif = "yes" ;; +esac + case "$with_menubars" in "" | "yes" | "athena" ) with_menubars="lucid" ;; esac case "$with_dialogs" in "" | "yes" | "lucid" ) - if test "$have_motif" = "yes"; then with_dialogs="motif" - elif test "$have_xaw" = "yes"; then with_dialogs="athena" - else with_dialogs=no + if test "$lucid_prefers_motif" = "yes"; then + if test "$have_motif" = "yes"; then with_dialogs="motif" + elif test "$have_xaw" = "yes"; then with_dialogs="athena" + else with_dialogs=no + fi + else + if test "$have_xaw" = "yes"; then with_dialogs="athena" + elif test "$have_motif" = "yes"; then with_dialogs="motif" + else with_dialogs=no + fi fi ;; esac case "$with_scrollbars" in "" | "yes" ) @@ -9631,9 +9654,16 @@ esac case "$with_widgets" in "yes" | "lucid") - if test "$have_motif" = "yes"; then with_widgets="motif" - elif test "$have_xaw" = "yes"; then with_widgets="athena" - else with_widgets=no + if test "$lucid_prefers_motif" = "yes"; then + if test "$have_motif" = "yes"; then with_widgets="motif" + elif test "$have_xaw" = "yes"; then with_widgets="athena" + else with_widgets=no + fi + else + if test "$have_xaw" = "yes"; then with_widgets="athena" + elif test "$have_motif" = "yes"; then with_widgets="motif" + else with_widgets=no + fi fi ;; "" ) with_widgets=no ;; @@ -10021,7 +10051,7 @@ if test "$with_mule" = "yes" ; then echo "checking for Mule-related features" 1>&6 -echo "configure:10025: checking for Mule-related features" >&5 +echo "configure:10055: checking for Mule-related features" >&5 { test "$extra_verbose" = "yes" && cat << \EOF Defining MULE EOF @@ -10046,15 +10076,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:10050: checking for $ac_hdr" >&5 +echo "configure:10080: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10058: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10088: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10085,12 +10115,12 @@ echo $ac_n "checking for strerror in -lintl""... $ac_c" 1>&6 -echo "configure:10089: checking for strerror in -lintl" >&5 +echo "configure:10119: checking for strerror in -lintl" >&5 ac_lib_var=`echo intl'_'strerror | sed 'y%./+-%__p_%'` xe_check_libs=" -lintl " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10134,18 +10164,18 @@ echo "checking for Mule input methods" 1>&6 -echo "configure:10138: checking for Mule input methods" >&5 +echo "configure:10168: checking for Mule input methods" >&5 case "$with_xim" in "" | "yes" ) echo "checking for XIM" 1>&6 -echo "configure:10141: checking for XIM" >&5 +echo "configure:10171: checking for XIM" >&5 echo $ac_n "checking for XOpenIM in -lX11""... $ac_c" 1>&6 -echo "configure:10144: checking for XOpenIM in -lX11" >&5 +echo "configure:10174: checking for XOpenIM in -lX11" >&5 ac_lib_var=`echo X11'_'XOpenIM | sed 'y%./+-%__p_%'` xe_check_libs=" -lX11 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10177,15 +10207,15 @@ fi - if test "$have_motif $have_lesstif" = "yes no"; then + if test "$need_motif $have_lesstif" = "yes no"; then echo $ac_n "checking for XmImMbLookupString in -lXm""... $ac_c" 1>&6 -echo "configure:10184: checking for XmImMbLookupString in -lXm" >&5 +echo "configure:10214: checking for XmImMbLookupString in -lXm" >&5 ac_lib_var=`echo Xm'_'XmImMbLookupString | sed 'y%./+-%__p_%'` xe_check_libs=" -lXm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +xe_check_libs="" + +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes" ; then + echo "$ac_t""yes" 1>&6 + with_xim=motif +else + echo "$ac_t""no" 1>&6 +fi + + + elif test "$have_motif $have_lesstif $with_xim" = "yes no no"; then + +echo $ac_n "checking for XmImMbLookupString in -lXm""... $ac_c" 1>&6 +echo "configure:10253: checking for XmImMbLookupString in -lXm" >&5 +ac_lib_var=`echo Xm'_'XmImMbLookupString | sed 'y%./+-%__p_%'` + +xe_check_libs=" -lXm " +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10261,15 +10330,15 @@ if test "$with_xfs" = "yes" ; then echo "checking for XFontSet" 1>&6 -echo "configure:10265: checking for XFontSet" >&5 +echo "configure:10334: checking for XFontSet" >&5 echo $ac_n "checking for XmbDrawString in -lX11""... $ac_c" 1>&6 -echo "configure:10268: checking for XmbDrawString in -lX11" >&5 +echo "configure:10337: checking for XmbDrawString in -lX11" >&5 ac_lib_var=`echo X11'_'XmbDrawString | sed 'y%./+-%__p_%'` xe_check_libs=" -lX11 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10320,15 +10389,15 @@ test "$with_wnn6" = "yes" && with_wnn=yes # wnn6 implies wnn support test -z "$with_wnn" && { ac_safe=`echo "wnn/jllib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for wnn/jllib.h""... $ac_c" 1>&6 -echo "configure:10324: checking for wnn/jllib.h" >&5 +echo "configure:10393: checking for wnn/jllib.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10332: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10401: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10351,15 +10420,15 @@ } test -z "$with_wnn" && { ac_safe=`echo "wnn/commonhd.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for wnn/commonhd.h""... $ac_c" 1>&6 -echo "configure:10355: checking for wnn/commonhd.h" >&5 +echo "configure:10424: checking for wnn/commonhd.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10363: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10384,10 +10453,10 @@ for ac_func in crypt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:10388: checking for $ac_func" >&5 +echo "configure:10457: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10483: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -10439,12 +10508,12 @@ test "$ac_cv_func_crypt" != "yes" && { echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:10443: checking for crypt in -lcrypt" >&5 +echo "configure:10512: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` xe_check_libs=" -lcrypt " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10490,12 +10559,12 @@ if test -z "$with_wnn" -o "$with_wnn" = "yes"; then echo $ac_n "checking for jl_dic_list_e in -lwnn""... $ac_c" 1>&6 -echo "configure:10494: checking for jl_dic_list_e in -lwnn" >&5 +echo "configure:10563: checking for jl_dic_list_e in -lwnn" >&5 ac_lib_var=`echo wnn'_'jl_dic_list_e | sed 'y%./+-%__p_%'` xe_check_libs=" -lwnn " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10524,12 +10593,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for jl_dic_list_e in -lwnn4""... $ac_c" 1>&6 -echo "configure:10528: checking for jl_dic_list_e in -lwnn4" >&5 +echo "configure:10597: checking for jl_dic_list_e in -lwnn4" >&5 ac_lib_var=`echo wnn4'_'jl_dic_list_e | sed 'y%./+-%__p_%'` xe_check_libs=" -lwnn4 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10558,12 +10627,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for jl_dic_list_e in -lwnn6""... $ac_c" 1>&6 -echo "configure:10562: checking for jl_dic_list_e in -lwnn6" >&5 +echo "configure:10631: checking for jl_dic_list_e in -lwnn6" >&5 ac_lib_var=`echo wnn6'_'jl_dic_list_e | sed 'y%./+-%__p_%'` xe_check_libs=" -lwnn6 " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10592,12 +10661,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dic_list_e in -lwnn6_fromsrc""... $ac_c" 1>&6 -echo "configure:10596: checking for dic_list_e in -lwnn6_fromsrc" >&5 +echo "configure:10665: checking for dic_list_e in -lwnn6_fromsrc" >&5 ac_lib_var=`echo wnn6_fromsrc'_'dic_list_e | sed 'y%./+-%__p_%'` xe_check_libs=" -lwnn6_fromsrc " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10656,12 +10725,12 @@ if test "$with_wnn6" != "no"; then echo $ac_n "checking for jl_fi_dic_list in -l$libwnn""... $ac_c" 1>&6 -echo "configure:10660: checking for jl_fi_dic_list in -l$libwnn" >&5 +echo "configure:10729: checking for jl_fi_dic_list in -l$libwnn" >&5 ac_lib_var=`echo $libwnn'_'jl_fi_dic_list | sed 'y%./+-%__p_%'` xe_check_libs=" -l$libwnn " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10707,15 +10776,15 @@ if test "$with_canna" != "no"; then ac_safe=`echo "canna/jrkanji.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for canna/jrkanji.h""... $ac_c" 1>&6 -echo "configure:10711: checking for canna/jrkanji.h" >&5 +echo "configure:10780: checking for canna/jrkanji.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10719: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10742,15 +10811,15 @@ c_switch_site="$c_switch_site -I/usr/local/canna/include" ac_safe=`echo "canna/jrkanji.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for canna/jrkanji.h""... $ac_c" 1>&6 -echo "configure:10746: checking for canna/jrkanji.h" >&5 +echo "configure:10815: checking for canna/jrkanji.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10754: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10823: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10778,15 +10847,15 @@ test -z "$with_canna" && { ac_safe=`echo "canna/RK.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for canna/RK.h""... $ac_c" 1>&6 -echo "configure:10782: checking for canna/RK.h" >&5 +echo "configure:10851: checking for canna/RK.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10790: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10859: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10809,12 +10878,12 @@ } test -z "$with_canna" && { echo $ac_n "checking for RkBgnBun in -lRKC""... $ac_c" 1>&6 -echo "configure:10813: checking for RkBgnBun in -lRKC" >&5 +echo "configure:10882: checking for RkBgnBun in -lRKC" >&5 ac_lib_var=`echo RKC'_'RkBgnBun | sed 'y%./+-%__p_%'` xe_check_libs=" -lRKC " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10848,12 +10917,12 @@ } test -z "$with_canna" && { echo $ac_n "checking for jrKanjiControl in -lcanna""... $ac_c" 1>&6 -echo "configure:10852: checking for jrKanjiControl in -lcanna" >&5 +echo "configure:10921: checking for jrKanjiControl in -lcanna" >&5 ac_lib_var=`echo canna'_'jrKanjiControl | sed 'y%./+-%__p_%'` xe_check_libs=" -lcanna " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:10937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10913,12 +10982,12 @@ libs_x="-lXm $libs_x" && if test "$extra_verbose" = "yes"; then echo " Prepending \"-lXm\" to \$libs_x"; fi echo $ac_n "checking for layout_object_getvalue in -li18n""... $ac_c" 1>&6 -echo "configure:10917: checking for layout_object_getvalue in -li18n" >&5 +echo "configure:10986: checking for layout_object_getvalue in -li18n" >&5 ac_lib_var=`echo i18n'_'layout_object_getvalue | sed 'y%./+-%__p_%'` xe_check_libs=" -li18n " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -10986,7 +11055,7 @@ eval "$xe_add_unique_runpath_dir" };; esac done - if test "$opsys $need_motif" = "sol2 yes"; then + if test "$opsys $need_motif" = "sol2 yes"; then xe_runpath_dir="/opt/SUNWdt/lib"; eval "$xe_add_unique_runpath_dir"; fi @@ -11016,10 +11085,10 @@ for ac_func in cbrt closedir dup2 eaccess fmod fpathconf frexp ftime getaddrinfo gethostname getnameinfo getpagesize gettimeofday getcwd getwd logb lrand48 matherr mkdir mktime perror poll random rename res_init rint rmdir select setitimer setpgid setlocale setsid sigblock sighold sigprocmask snprintf stpcpy strerror tzset ulimit usleep waitpid vsnprintf fsync ftruncate umask do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11020: checking for $ac_func" >&5 +echo "configure:11089: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11083,10 +11152,10 @@ for ac_func in getpt _getpty grantpt unlockpt ptsname killpg tcgetpgrp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11087: checking for $ac_func" >&5 +echo "configure:11156: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11138,10 +11207,10 @@ echo $ac_n "checking for openpty""... $ac_c" 1>&6 -echo "configure:11142: checking for openpty" >&5 +echo "configure:11211: checking for openpty" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_openpty=yes" else @@ -11183,12 +11252,12 @@ echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 -echo "configure:11187: checking for openpty in -lutil" >&5 +echo "configure:11256: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` xe_check_libs=" -lutil " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11234,15 +11303,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11238: checking for $ac_hdr" >&5 +echo "configure:11307: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11315: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -11278,15 +11347,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11282: checking for $ac_hdr" >&5 +echo "configure:11351: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11290: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11359: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -11319,10 +11388,10 @@ for ac_func in isastream do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11323: checking for $ac_func" >&5 +echo "configure:11392: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11376,15 +11445,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11380: checking for $ac_hdr" >&5 +echo "configure:11449: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11457: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -11421,10 +11490,10 @@ for ac_func in getloadavg do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:11425: checking for $ac_func" >&5 +echo "configure:11494: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -11480,15 +11549,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11484: checking for $ac_hdr" >&5 +echo "configure:11553: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11492: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11561: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -11524,12 +11593,12 @@ echo $ac_n "checking for kstat_open in -lkstat""... $ac_c" 1>&6 -echo "configure:11528: checking for kstat_open in -lkstat" >&5 +echo "configure:11597: checking for kstat_open in -lkstat" >&5 ac_lib_var=`echo kstat'_'kstat_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lkstat " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11575,15 +11644,15 @@ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11579: checking for $ac_hdr" >&5 +echo "configure:11648: checking for $ac_hdr" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11587: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -11615,12 +11684,12 @@ echo $ac_n "checking for kvm_read in -lkvm""... $ac_c" 1>&6 -echo "configure:11619: checking for kvm_read in -lkvm" >&5 +echo "configure:11688: checking for kvm_read in -lkvm" >&5 ac_lib_var=`echo kvm'_'kvm_read | sed 'y%./+-%__p_%'` xe_check_libs=" -lkvm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11665,16 +11734,16 @@ fi echo $ac_n "checking whether netdb declares h_errno""... $ac_c" 1>&6 -echo "configure:11669: checking whether netdb declares h_errno" >&5 +echo "configure:11738: checking whether netdb declares h_errno" >&5 cat > conftest.$ac_ext < int main() { return h_errno; ; return 0; } EOF -if { (eval echo configure:11678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 { test "$extra_verbose" = "yes" && cat << \EOF @@ -11694,16 +11763,16 @@ rm -f conftest* echo $ac_n "checking for sigsetjmp""... $ac_c" 1>&6 -echo "configure:11698: checking for sigsetjmp" >&5 +echo "configure:11767: checking for sigsetjmp" >&5 cat > conftest.$ac_ext < int main() { sigjmp_buf bar; sigsetjmp (bar, 0); ; return 0; } EOF -if { (eval echo configure:11707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11776: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 { test "$extra_verbose" = "yes" && cat << \EOF @@ -11723,11 +11792,11 @@ rm -f conftest* echo $ac_n "checking whether localtime caches TZ""... $ac_c" 1>&6 -echo "configure:11727: checking whether localtime caches TZ" >&5 +echo "configure:11796: checking whether localtime caches TZ" >&5 if test "$ac_cv_func_tzset" = "yes"; then cat > conftest.$ac_ext < #if STDC_HEADERS @@ -11762,7 +11831,7 @@ exit (0); } EOF -if { (eval echo configure:11766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:11835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then emacs_cv_localtime_cache=no else @@ -11792,9 +11861,9 @@ if test "$HAVE_TIMEVAL" = "yes"; then echo $ac_n "checking whether gettimeofday accepts one or two arguments""... $ac_c" 1>&6 -echo "configure:11796: checking whether gettimeofday accepts one or two arguments" >&5 +echo "configure:11865: checking whether gettimeofday accepts one or two arguments" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""two" 1>&6 else @@ -11837,19 +11906,19 @@ echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:11841: checking for inline" >&5 +echo "configure:11910: checking for inline" >&5 ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11922: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -11890,17 +11959,17 @@ # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:11894: checking for working alloca.h" >&5 +echo "configure:11963: checking for working alloca.h" >&5 cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:11904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -11924,10 +11993,10 @@ fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:11928: checking for alloca" >&5 +echo "configure:11997: checking for alloca" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12028: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -11994,10 +12063,10 @@ echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:11998: checking whether alloca needs Cray hooks" >&5 +echo "configure:12067: checking whether alloca needs Cray hooks" >&5 cat > conftest.$ac_ext <&6 -echo "configure:12025: checking for $ac_func" >&5 +echo "configure:12094: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12077,10 +12146,10 @@ fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:12081: checking stack direction for C alloca" >&5 +echo "configure:12150: checking stack direction for C alloca" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:12172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_c_stack_direction=1 else @@ -12129,15 +12198,15 @@ ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for vfork.h""... $ac_c" 1>&6 -echo "configure:12133: checking for vfork.h" >&5 +echo "configure:12202: checking for vfork.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12210: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12165,10 +12234,10 @@ fi echo $ac_n "checking for working vfork""... $ac_c" 1>&6 -echo "configure:12169: checking for working vfork" >&5 +echo "configure:12238: checking for working vfork" >&5 cat > conftest.$ac_ext < @@ -12263,7 +12332,7 @@ } } EOF -if { (eval echo configure:12267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:12336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_func_vfork_works=yes else @@ -12289,10 +12358,10 @@ echo $ac_n "checking for working strcoll""... $ac_c" 1>&6 -echo "configure:12293: checking for working strcoll" >&5 +echo "configure:12362: checking for working strcoll" >&5 cat > conftest.$ac_ext < main () @@ -12302,7 +12371,7 @@ strcoll ("123", "456") >= 0); } EOF -if { (eval echo configure:12306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:12375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_func_strcoll_works=yes else @@ -12330,10 +12399,10 @@ for ac_func in getpgrp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:12334: checking for $ac_func" >&5 +echo "configure:12403: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12429: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -12384,10 +12453,10 @@ done echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6 -echo "configure:12388: checking whether getpgrp takes no argument" >&5 +echo "configure:12457: checking whether getpgrp takes no argument" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:12515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then ac_cv_func_getpgrp_void=yes else @@ -12469,10 +12538,10 @@ echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:12473: checking for working mmap" >&5 +echo "configure:12542: checking for working mmap" >&5 case "$opsys" in ultrix* ) have_mmap=no ;; *) cat > conftest.$ac_ext < #include @@ -12505,7 +12574,7 @@ return 1; } EOF -if { (eval echo configure:12509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:12578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then have_mmap=yes else @@ -12534,9 +12603,9 @@ if test "$rel_alloc $have_mmap" = "default yes"; then if test "$doug_lea_malloc" = "yes"; then echo $ac_n "checking for M_MMAP_THRESHOLD""... $ac_c" 1>&6 -echo "configure:12538: checking for M_MMAP_THRESHOLD" >&5 +echo "configure:12607: checking for M_MMAP_THRESHOLD" >&5 cat > conftest.$ac_ext < int main() { @@ -12548,7 +12617,7 @@ ; return 0; } EOF -if { (eval echo configure:12552: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:12621: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* rel_alloc=no; echo "$ac_t""yes" 1>&6; else @@ -12573,15 +12642,15 @@ ac_safe=`echo "termios.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for termios.h""... $ac_c" 1>&6 -echo "configure:12577: checking for termios.h" >&5 +echo "configure:12646: checking for termios.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12654: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12624,15 +12693,15 @@ echo "$ac_t""no" 1>&6 ac_safe=`echo "termio.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for termio.h""... $ac_c" 1>&6 -echo "configure:12628: checking for termio.h" >&5 +echo "configure:12697: checking for termio.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12636: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12705: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12664,10 +12733,10 @@ echo $ac_n "checking for socket""... $ac_c" 1>&6 -echo "configure:12668: checking for socket" >&5 +echo "configure:12737: checking for socket" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else @@ -12705,15 +12774,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "netinet/in.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for netinet/in.h""... $ac_c" 1>&6 -echo "configure:12709: checking for netinet/in.h" >&5 +echo "configure:12778: checking for netinet/in.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12717: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12730,15 +12799,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "arpa/inet.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for arpa/inet.h""... $ac_c" 1>&6 -echo "configure:12734: checking for arpa/inet.h" >&5 +echo "configure:12803: checking for arpa/inet.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12742: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12811: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12763,9 +12832,9 @@ } echo $ac_n "checking "for sun_len member in struct sockaddr_un"""... $ac_c" 1>&6 -echo "configure:12767: checking "for sun_len member in struct sockaddr_un"" >&5 +echo "configure:12836: checking "for sun_len member in struct sockaddr_un"" >&5 cat > conftest.$ac_ext < @@ -12776,7 +12845,7 @@ static struct sockaddr_un x; x.sun_len = 1; ; return 0; } EOF -if { (eval echo configure:12780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_SOCKADDR_SUN_LEN @@ -12794,9 +12863,9 @@ fi rm -f conftest* echo $ac_n "checking "for ip_mreq struct in netinet/in.h"""... $ac_c" 1>&6 -echo "configure:12798: checking "for ip_mreq struct in netinet/in.h"" >&5 +echo "configure:12867: checking "for ip_mreq struct in netinet/in.h"" >&5 cat > conftest.$ac_ext < @@ -12806,7 +12875,7 @@ static struct ip_mreq x; ; return 0; } EOF -if { (eval echo configure:12810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_MULTICAST @@ -12837,10 +12906,10 @@ echo $ac_n "checking for msgget""... $ac_c" 1>&6 -echo "configure:12841: checking for msgget" >&5 +echo "configure:12910: checking for msgget" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:12936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_msgget=yes" else @@ -12878,15 +12947,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "sys/ipc.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/ipc.h""... $ac_c" 1>&6 -echo "configure:12882: checking for sys/ipc.h" >&5 +echo "configure:12951: checking for sys/ipc.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12890: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12959: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12903,15 +12972,15 @@ echo "$ac_t""yes" 1>&6 ac_safe=`echo "sys/msg.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/msg.h""... $ac_c" 1>&6 -echo "configure:12907: checking for sys/msg.h" >&5 +echo "configure:12976: checking for sys/msg.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12915: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:12984: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12949,15 +13018,15 @@ ac_safe=`echo "dirent.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for dirent.h""... $ac_c" 1>&6 -echo "configure:12953: checking for dirent.h" >&5 +echo "configure:13022: checking for dirent.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12961: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13030: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12984,15 +13053,15 @@ echo "$ac_t""no" 1>&6 ac_safe=`echo "sys/dir.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/dir.h""... $ac_c" 1>&6 -echo "configure:12988: checking for sys/dir.h" >&5 +echo "configure:13057: checking for sys/dir.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:12996: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13065: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13025,15 +13094,15 @@ ac_safe=`echo "nlist.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for nlist.h""... $ac_c" 1>&6 -echo "configure:13029: checking for nlist.h" >&5 +echo "configure:13098: checking for nlist.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13037: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13063,22 +13132,22 @@ echo "checking "for sound support"" 1>&6 -echo "configure:13067: checking "for sound support"" >&5 +echo "configure:13136: checking "for sound support"" >&5 test -z "$with_native_sound" -a -n "$native_sound_lib" && with_native_sound=yes if test "$with_native_sound" != "no"; then if test -n "$native_sound_lib"; then ac_safe=`echo "multimedia/audio_device.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for multimedia/audio_device.h""... $ac_c" 1>&6 -echo "configure:13074: checking for multimedia/audio_device.h" >&5 +echo "configure:13143: checking for multimedia/audio_device.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13082: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13151: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13104,19 +13173,27 @@ fi if test -z "$sound_found" -a -d "/usr/demo/SOUND"; then - sound_found=yes - extra_objs="$extra_objs sunplay.o" && if test "$extra_verbose" = "yes"; then + if test -d "/usr/demo/SOUND/include/multimedia"; then + sun_sound_cflags="-I/usr/demo/SOUND/include" + elif test -d "/usr/demo/SOUND/multimedia"; then + sun_sound_cflags="-I/usr/demo/SOUND" + fi + + if test -n "$native_sound_lib"; then + sun_sound_lib="$native_sound_lib" + elif test -r "/usr/demo/SOUND/lib/libaudio.a"; then + sun_sound_lib="/usr/demo/SOUND/lib/libaudio.a" + elif test -r "/usr/demo/SOUND/libaudio.a"; then + sun_sound_lib="/usr/demo/SOUND/libaudio.a" + fi + + if test -n "$sun_sound_cflags" -a -n "$sun_sound_lib"; then + native_sound_lib="$sun_sound_lib" + sound_cflags="$sun_sound_cflags" + sound_found=yes + extra_objs="$extra_objs sunplay.o" && if test "$extra_verbose" = "yes"; then echo " xemacs will be linked with \"sunplay.o\"" fi - if test -d "/usr/demo/SOUND/include" - then sound_cflags="-I/usr/demo/SOUND/include" - else sound_cflags="-I/usr/demo/SOUND" - fi - if test -z "$native_sound_lib" ; then - if test -r "/usr/demo/SOUND/lib/libaudio.a" - then native_sound_lib="/usr/demo/SOUND/lib/libaudio.a" - else native_sound_lib="/usr/demo/SOUND/libaudio.a" - fi fi fi @@ -13126,12 +13203,12 @@ if test -z "$native_sound_lib"; then echo $ac_n "checking for ALopenport in -laudio""... $ac_c" 1>&6 -echo "configure:13130: checking for ALopenport in -laudio" >&5 +echo "configure:13207: checking for ALopenport in -laudio" >&5 ac_lib_var=`echo audio'_'ALopenport | sed 'y%./+-%__p_%'` xe_check_libs=" -laudio " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13173,12 +13250,12 @@ if test -z "$native_sound_lib"; then echo $ac_n "checking for AOpenAudio in -lAlib""... $ac_c" 1>&6 -echo "configure:13177: checking for AOpenAudio in -lAlib" >&5 +echo "configure:13254: checking for AOpenAudio in -lAlib" >&5 ac_lib_var=`echo Alib'_'AOpenAudio | sed 'y%./+-%__p_%'` xe_check_libs=" -lAlib " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13234,15 +13311,15 @@ for dir in "machine" "sys" "linux"; do ac_safe=`echo "${dir}/soundcard.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ${dir}/soundcard.h""... $ac_c" 1>&6 -echo "configure:13238: checking for ${dir}/soundcard.h" >&5 +echo "configure:13315: checking for ${dir}/soundcard.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13323: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13296,15 +13373,15 @@ if test "$with_nas_sound" != "no"; then ac_safe=`echo "audio/audiolib.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for audio/audiolib.h""... $ac_c" 1>&6 -echo "configure:13300: checking for audio/audiolib.h" >&5 +echo "configure:13377: checking for audio/audiolib.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13308: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13322,12 +13399,12 @@ echo $ac_n "checking for AuOpenServer in -laudio""... $ac_c" 1>&6 -echo "configure:13326: checking for AuOpenServer in -laudio" >&5 +echo "configure:13403: checking for AuOpenServer in -laudio" >&5 ac_lib_var=`echo audio'_'AuOpenServer | sed 'y%./+-%__p_%'` xe_check_libs=" -laudio " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13377,7 +13454,7 @@ fi libs_x="-laudio $libs_x" && if test "$extra_verbose" = "yes"; then echo " Prepending \"-laudio\" to \$libs_x"; fi cat > conftest.$ac_ext < EOF @@ -13408,7 +13485,7 @@ # Extract the first word of "esd-config", so it can be a program name with args. set dummy esd-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:13412: checking for $ac_word" >&5 +echo "configure:13489: checking for $ac_word" >&5 if test -n "$have_esd_config"; then ac_cv_prog_have_esd_config="$have_esd_config" # Let the user override the test. @@ -13437,10 +13514,10 @@ c_switch_site="$c_switch_site `esd-config --cflags`" && if test "$extra_verbose" = "yes"; then echo " Appending \"`esd-config --cflags`\" to \$c_switch_site"; fi LIBS="`esd-config --libs` $LIBS" && if test "$extra_verbose" = "yes"; then echo " Prepending \"`esd-config --libs`\" to \$LIBS"; fi echo $ac_n "checking for esd_play_stream""... $ac_c" 1>&6 -echo "configure:13441: checking for esd_play_stream" >&5 +echo "configure:13518: checking for esd_play_stream" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_esd_play_stream=yes" else @@ -13514,7 +13591,7 @@ if test "$with_tty" = "yes" ; then echo "checking for TTY-related features" 1>&6 -echo "configure:13518: checking for TTY-related features" >&5 +echo "configure:13595: checking for TTY-related features" >&5 { test "$extra_verbose" = "yes" && cat << \EOF Defining HAVE_TTY EOF @@ -13530,12 +13607,12 @@ if test -z "$with_ncurses"; then echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6 -echo "configure:13534: checking for tgetent in -lncurses" >&5 +echo "configure:13611: checking for tgetent in -lncurses" >&5 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'` xe_check_libs=" -lncurses " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13579,15 +13656,15 @@ ac_safe=`echo "ncurses/curses.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ncurses/curses.h""... $ac_c" 1>&6 -echo "configure:13583: checking for ncurses/curses.h" >&5 +echo "configure:13660: checking for ncurses/curses.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13668: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13609,15 +13686,15 @@ ac_safe=`echo "ncurses/term.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ncurses/term.h""... $ac_c" 1>&6 -echo "configure:13613: checking for ncurses/term.h" >&5 +echo "configure:13690: checking for ncurses/term.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13621: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13698: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13647,15 +13724,15 @@ c_switch_site="$c_switch_site -I/usr/include/ncurses" ac_safe=`echo "ncurses/curses.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ncurses/curses.h""... $ac_c" 1>&6 -echo "configure:13651: checking for ncurses/curses.h" >&5 +echo "configure:13728: checking for ncurses/curses.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13659: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13690,12 +13767,12 @@ for lib in curses termlib termcap; do echo $ac_n "checking for tgetent in -l$lib""... $ac_c" 1>&6 -echo "configure:13694: checking for tgetent in -l$lib" >&5 +echo "configure:13771: checking for tgetent in -l$lib" >&5 ac_lib_var=`echo $lib'_'tgetent | sed 'y%./+-%__p_%'` xe_check_libs=" -l$lib " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13731,12 +13808,12 @@ else if test -n "$libs_termcap" -a "$opsys" = "openbsd"; then echo $ac_n "checking for tgoto in -ltermcap""... $ac_c" 1>&6 -echo "configure:13735: checking for tgoto in -ltermcap" >&5 +echo "configure:13812: checking for tgoto in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgoto | sed 'y%./+-%__p_%'` xe_check_libs=" -ltermcap " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13792,12 +13869,12 @@ else echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6 -echo "configure:13796: checking for tgetent in -lcurses" >&5 +echo "configure:13873: checking for tgetent in -lcurses" >&5 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'` xe_check_libs=" -lcurses " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13826,12 +13903,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 -echo "configure:13830: checking for tgetent in -ltermcap" >&5 +echo "configure:13907: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` xe_check_libs=" -ltermcap " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13890,15 +13967,15 @@ test -z "$with_gpm" && { ac_safe=`echo "gpm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for gpm.h""... $ac_c" 1>&6 -echo "configure:13894: checking for gpm.h" >&5 +echo "configure:13971: checking for gpm.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:13902: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:13979: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -13921,12 +13998,12 @@ } test -z "$with_gpm" && { echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6 -echo "configure:13925: checking for Gpm_Open in -lgpm" >&5 +echo "configure:14002: checking for Gpm_Open in -lgpm" >&5 ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'` xe_check_libs=" -lgpm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13987,20 +14064,20 @@ test "$with_database_gdbm $with_database_dbm $with_database_berkdb" \ != "no no no" && echo "checking for database support" 1>&6 -echo "configure:13991: checking for database support" >&5 +echo "configure:14068: checking for database support" >&5 if test "$with_database_gdbm $with_database_dbm" != "no no"; then ac_safe=`echo "ndbm.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ndbm.h""... $ac_c" 1>&6 -echo "configure:13996: checking for ndbm.h" >&5 +echo "configure:14073: checking for ndbm.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:14004: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:14081: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -14030,12 +14107,12 @@ if test "$with_database_gdbm" != "no"; then echo $ac_n "checking for dbm_open in -lgdbm""... $ac_c" 1>&6 -echo "configure:14034: checking for dbm_open in -lgdbm" >&5 +echo "configure:14111: checking for dbm_open in -lgdbm" >&5 ac_lib_var=`echo gdbm'_'dbm_open | sed 'y%./+-%__p_%'` xe_check_libs=" -lgdbm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14074,10 +14151,10 @@ if test "$with_database_dbm" != "no"; then echo $ac_n "checking for dbm_open""... $ac_c" 1>&6 -echo "configure:14078: checking for dbm_open" >&5 +echo "configure:14155: checking for dbm_open" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_dbm_open=yes" else @@ -14119,12 +14196,12 @@ echo $ac_n "checking for dbm_open in -ldbm""... $ac_c" 1>&6 -echo "configure:14123: checking for dbm_open in -ldbm" >&5 +echo "configure:14200: checking for dbm_open in -ldbm" >&5 ac_lib_var=`echo dbm'_'dbm_open | sed 'y%./+-%__p_%'` xe_check_libs=" -ldbm " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14216: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14176,12 +14253,12 @@ if test "$with_database_berkdb" != "no"; then echo $ac_n "checking for Berkeley db.h""... $ac_c" 1>&6 -echo "configure:14180: checking for Berkeley db.h" >&5 +echo "configure:14257: checking for Berkeley db.h" >&5 for header in "db/db.h" "db.h"; do case "$opsys" in *freebsd*) cat > conftest.$ac_ext < @@ -14197,7 +14274,7 @@ ; return 0; } EOF -if { (eval echo configure:14201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14278: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* db_h_file="$header"; break else @@ -14208,7 +14285,7 @@ ;; *) cat > conftest.$ac_ext < @@ -14230,7 +14307,7 @@ ; return 0; } EOF -if { (eval echo configure:14234: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* db_h_file="$header"; break else @@ -14248,9 +14325,9 @@ if test "$with_database_berkdb" != "no"; then echo $ac_n "checking for Berkeley DB version""... $ac_c" 1>&6 -echo "configure:14252: checking for Berkeley DB version" >&5 +echo "configure:14329: checking for Berkeley DB version" >&5 cat > conftest.$ac_ext < #if DB_VERSION_MAJOR > 1 @@ -14262,7 +14339,7 @@ egrep "yes" >/dev/null 2>&1; then rm -rf conftest* cat > conftest.$ac_ext < #if DB_VERSION_MAJOR > 2 @@ -14289,10 +14366,10 @@ rm -f conftest* echo $ac_n "checking for $dbfunc""... $ac_c" 1>&6 -echo "configure:14293: checking for $dbfunc" >&5 +echo "configure:14370: checking for $dbfunc" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$dbfunc=yes" else @@ -14334,12 +14411,12 @@ echo $ac_n "checking for $dbfunc in -ldb""... $ac_c" 1>&6 -echo "configure:14338: checking for $dbfunc in -ldb" >&5 +echo "configure:14415: checking for $dbfunc in -ldb" >&5 ac_lib_var=`echo db'_'$dbfunc | sed 'y%./+-%__p_%'` xe_check_libs=" -ldb " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14414,12 +14491,12 @@ if test "$with_socks" = "yes"; then echo $ac_n "checking for SOCKSinit in -lsocks""... $ac_c" 1>&6 -echo "configure:14418: checking for SOCKSinit in -lsocks" >&5 +echo "configure:14495: checking for SOCKSinit in -lsocks" >&5 ac_lib_var=`echo socks'_'SOCKSinit | sed 'y%./+-%__p_%'` xe_check_libs=" -lsocks " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14485,7 +14562,7 @@ if test "$with_modules" != "no"; then echo "checking for module support" 1>&6 -echo "configure:14489: checking for module support" >&5 +echo "configure:14566: checking for module support" >&5 if test "$with_msw" = "yes"; then have_dl=yes; @@ -14501,15 +14578,15 @@ ;; *) ac_safe=`echo "dlfcn.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for dlfcn.h""... $ac_c" 1>&6 -echo "configure:14505: checking for dlfcn.h" >&5 +echo "configure:14582: checking for dlfcn.h" >&5 cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:14513: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:14590: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -14526,16 +14603,16 @@ echo "$ac_t""yes" 1>&6 echo $ac_n "checking for dlopen in -lc""... $ac_c" 1>&6 -echo "configure:14530: checking for dlopen in -lc" >&5 +echo "configure:14607: checking for dlopen in -lc" >&5 cat > conftest.$ac_ext < int main() { dlopen ("", 0); ; return 0; } EOF -if { (eval echo configure:14539: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_dl=yes else @@ -14544,18 +14621,18 @@ rm -rf conftest* echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:14548: checking for dlopen in -ldl" >&5 +echo "configure:14625: checking for dlopen in -ldl" >&5 ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext < int main() { dlopen ("", 0); ; return 0; } EOF -if { (eval echo configure:14559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_dl=yes else @@ -14584,12 +14661,12 @@ else echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "configure:14588: checking for shl_load in -ldld" >&5 +echo "configure:14665: checking for shl_load in -ldld" >&5 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` xe_check_libs=" -ldld " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14627,12 +14704,12 @@ echo "$ac_t""no" 1>&6 echo $ac_n "checking for dld_init in -ldld""... $ac_c" 1>&6 -echo "configure:14631: checking for dld_init in -ldld" >&5 +echo "configure:14708: checking for dld_init in -ldld" >&5 ac_lib_var=`echo dld'_'dld_init | sed 'y%./+-%__p_%'` xe_check_libs=" -ldld " cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14690,7 +14767,7 @@ xealias=$internal_configuration echo "checking how to build dynamic libraries for ${xehost}" 1>&6 -echo "configure:14694: checking how to build dynamic libraries for ${xehost}" >&5 +echo "configure:14771: checking how to build dynamic libraries for ${xehost}" >&5 # Transform *-*-linux* to *-*-linux-gnu*, to support old configure scripts. case "$xehost" in *-*-linux-gnu*) ;; @@ -14718,9 +14795,9 @@ XEGCC=yes else echo $ac_n "checking checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:14722: checking checking whether we are using GNU C" >&5 +echo "configure:14799: checking checking whether we are using GNU C" >&5 cat > conftest.$ac_ext <&6 -echo "configure:14746: checking how to produce PIC code" >&5 +echo "configure:14823: checking how to produce PIC code" >&5 wl= can_build_shared=yes -if test "$XEGCC" = yes; then +if test "$XEGCC" = yes -o "$__ICC" = yes; then wl='-Wl,' case "$xehost_os" in @@ -14843,18 +14920,18 @@ # Check to make sure the dll_cflags actually works. echo $ac_n "checking if PIC flag ${dll_cflags} really works""... $ac_c" 1>&6 -echo "configure:14847: checking if PIC flag ${dll_cflags} really works" >&5 +echo "configure:14924: checking if PIC flag ${dll_cflags} really works" >&5 save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $dll_cflags -DPIC" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:14935: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* # On HP-UX, the stripped-down bundled CC doesn't accept +Z, but also @@ -14885,8 +14962,8 @@ xldf= xcldf= echo $ac_n "checking if C compiler can produce shared libraries""... $ac_c" 1>&6 -echo "configure:14889: checking if C compiler can produce shared libraries" >&5 -if test "$XEGCC" = yes; then +echo "configure:14966: checking if C compiler can produce shared libraries" >&5 +if test "$XEGCC" = yes -o "$__ICC" = yes; then xcldf="-shared" xldf="-shared" else # Not using GCC @@ -14936,14 +15013,14 @@ xe_libs= ac_link='${CC-cc} -o conftest $CFLAGS '"$xe_cppflags $xe_ldflags"' conftest.$ac_ext '"$xe_libs"' 1>&5' cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* cc_produces_so=yes else @@ -14968,7 +15045,7 @@ if test "$XEGCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:14972: checking for ld used by GCC" >&5 +echo "configure:15049: checking for ld used by GCC" >&5 ac_prog=`($CC -print-prog-name=ld) 2>&5` case "$ac_prog" in # Accept absolute paths. @@ -14994,7 +15071,7 @@ esac else echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:14998: checking for GNU ld" >&5 +echo "configure:15075: checking for GNU ld" >&5 fi if test -z "$LTLD"; then @@ -15032,7 +15109,7 @@ # Check to see if it really is or isn't GNU ld. echo $ac_n "checking if the linker is GNU ld""... $ac_c" 1>&6 -echo "configure:15036: checking if the linker is GNU ld" >&5 +echo "configure:15113: checking if the linker is GNU ld" >&5 # I'd rather use --version here, but apparently some GNU ld's only accept -v. if $LTLD -v 2>&1 &5; then xe_gnu_ld=yes @@ -15060,7 +15137,7 @@ # OK - only NOW do we futz about with ld. # See if the linker supports building shared libraries. echo $ac_n "checking whether the linker supports shared libraries""... $ac_c" 1>&6 -echo "configure:15064: checking whether the linker supports shared libraries" >&5 +echo "configure:15141: checking whether the linker supports shared libraries" >&5 dll_ld=$CC dll_ldflags=$LDFLAGS ld_shlibs=yes @@ -15271,10 +15348,10 @@ for ac_func in dlerror _dlerror do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:15275: checking for $ac_func" >&5 +echo "configure:15352: checking for $ac_func" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -15336,11 +15413,11 @@ fi cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 +if { (eval echo configure:15421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5 then : else @@ -15980,6 +16057,66 @@ fi echo " Compiler: $CC $CFLAGS" +case "$CC" in + gcc*) echo " Compiler version: `$CC --version | head -1`" + echo " Compiler specs file: `$CC -v 2>&1 | sed 's/.* \([^ ]\)/\1/' | head -1`" + ;; + *) case "$canonical" in + *-*-aix* ) + realcc=`which $CC` + if test -L $realcc ; then + ccdir=`dirname $realcc` + ccprog=`/bin/ls -l $realcc | sed 's/.* \([^ ]\)/\1/'` + case $ccprog in + */*) realcc=$ccprog;; + *) realcc=$ccdir/$ccprog;; + esac + fi + lpp=`lslpp -wqc $realcc | cut -f2 -d:` + if test ! -z "$lpp" ; then + lppstr=`lslpp -Lqc $lpp` + lpplev=`echo "$lppstr" | cut -f3 -d:` + lppdesc=`echo "$lppstr" | cut -f8 -d:` + fi + if test ! -z "$lpplev" ; then + echo " Compiler version: $lpp $lpplev - $lppdesc" + else + echo " Compiler version: (unknown version)" + fi + ;; + + *-*-solaris*) + ccvers=`$CC -V 2>&1 | head -1` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + alpha*-dec-osf*) + ccvers=`$CC -V | tr '\n' ' '` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + mips-sgi-irix*) + ccvers=`$CC -version` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + i[3-9]86-pc-linux) + ccvers=`$CC -V 2>&1 | sed -n 's@^Intel.*Version @@'p` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + *) echo " Compiler version: $CC on $canonical";; + esac +esac + echo " Relocating allocator for buffers: $rel_alloc" echo " GNU version of malloc: ${GNU_MALLOC}${GNU_MALLOC_reason}" case "$ld_switch_site" in @@ -15987,6 +16124,42 @@ - Consider configuring with --pdump." ;; esac +case "$canonical" in + *-*-linux*) + if test -f /etc/redhat-release ; then + echo " libc: `rpm -q glibc`"; + else + echo "Need to guess glibc1/2/etc here"; + fi + ;; + + *-*-aix*) + echo " libc: bos.rte.libc `lslpp -Lqc bos.rte.libc | cut -f3 -d:`" + ;; + + *-*-solaris*) + libc=`pkginfo -l SUNWcsl | grep VERSION: | awk '{print $2}'` + echo " libc: SUNWcsl $libc" + + ;; + + mips-sgi-irix*) + echo " IRIX version: `uname -sRm`'" + ;; + + + alpha*-dec-osf*) + (cd /usr/.smdb.; + libc=` grep -h libc.so *.inv | awk '$9 == "f" {print $12}' | tr '\n' ','` + echo " libc: $libc" + + ) + ;; + + *) echo " libc: system-provided libc on $canonical" ;; +esac + + echo " Window System:" if test "$with_msw" = "yes"; then @@ -16008,6 +16181,9 @@ fi if test "$need_motif" = "yes" ; then echo " Compiling in support for Motif." + if test "$have_lesstif" = "yes"; then + echo " - Using LessTif implementation." + fi echo " *WARNING* Many versions of Motif are buggy, requiring workarounds." echo " You are likely to experience slow redisplay." echo " You may need to install vendor patches to Motif." diff -u -r -N xemacs-21.4.14/configure.in xemacs-21.4.15/configure.in --- xemacs-21.4.14/configure.in 2003-08-17 21:43:21.000000000 -0400 +++ xemacs-21.4.15/configure.in 2004-01-23 23:37:54.000000000 -0500 @@ -348,6 +348,7 @@ with_site_modules='yes' with_menubars='' with_scrollbars='' +dnl can't turn off widgets here because of systems where they are demanded with_widgets='' with_dialogs='' with_file_coding='' @@ -1451,9 +1452,14 @@ esac case "$canonical" in - *-solaris* ) + *-solaris* ) opsys=sol2 - os_release=`uname -r | sed -e 's/^\([[0-9]]\)\.\([[0-9]]\).*/\1\2/'` + os_release_major=`uname -r | sed -e 's/^\([[0-9]]\{1,\}\)\.\([[0-9]]\{1,\}\).*/\1/'` + os_release_minor=`uname -r | sed -e 's/^\([[0-9]]\{1,\}\)\.\([[0-9]]\{1,\}\).*/\2/'` + case "$os_release_minor" in [[0-9]]) + os_release_minor="0${os_release_minor}";; + esac + os_release="${os_release_major}${os_release_minor}" AC_DEFINE_UNQUOTED(OS_RELEASE, $os_release) ;; dnl The last Sun386 ran 4.0. @@ -1703,7 +1709,7 @@ sol2) AC_DEFINE(__EXTENSIONS__) dnl Solaris 2 before 2.5 had some bugs with feature test macro interaction. - if test "$os_release" -ge 55; then + if test "$os_release" -ge 505; then AC_DEFINE(_XOPEN_SOURCE,500) AC_DEFINE(_XOPEN_SOURCE_EXTENDED) fi ;; @@ -1724,14 +1730,19 @@ return 12; #elif defined __USLC__ && defined __SCO_VERSION__ return 13; +#elif defined __INTEL_COMPILER +return 14; #else return 0; #endif }], [], [case "$conftest_rc" in - 11) echo "You appear to be using the SunPro C compiler."; __SUNPRO_C=yes ;; - 12) echo "You appear to be using the DEC C compiler." ; __DECC=yes ;; - 13) echo "You appear to be using the SCO C compiler." ; __USLC__=yes ;; + 11) echo "You appear to be using the SunPro C compiler." ; __SUNPRO_C=yes ;; + 12) echo "You appear to be using the DEC C compiler." ; __DECC=yes ;; + 13) echo "You appear to be using the SCO C compiler." ; __USLC__=yes ;; + 14) echo "You appear to be using the Intel C++ compiler."; __ICC=yes + dnl Newer versions of icc claim to be GCC + GCC=no ;; esac]) @@ -1950,6 +1961,8 @@ CFLAGS="-O3" elif test "$CC" = "xlc"; then CFLAGS="-g -O3 -qstrict -qnoansialias -qlibansi -qinfo -qro -qmaxmem=20000" + elif test "$__ICC" = "yes"; then + CFLAGS="-g -O3 -Ob2 -Wall -W1" dnl ### Add optimal CFLAGS support for other compilers HERE! else CFLAGS="-O" ;dnl The only POSIX-approved flag @@ -2301,6 +2314,7 @@ case "$arg" in -L*) XE_ADD_RUNPATH_DIR(`echo '' "$arg" | sed -e 's:^ ::' -e 's/^-L//'`);; esac done dnl Sometimes /opt/SUNWdt/lib is the only installed Motif available + dnl #### this test always fails here as need_motif is null if test "$opsys $need_motif" = "sol2 yes"; then xe_runpath_dir="/opt/SUNWdt/lib"; eval "$xe_add_unique_runpath_dir"; @@ -2563,7 +2577,7 @@ dnl Link with "-z ignore" on Solaris if supported if test "$opsys" = "sol2"; then - if test "$os_release" -ge 56; then + if test "$os_release" -ge 506; then AC_MSG_CHECKING(for \"-z ignore\" linker flag) case "`ld -h 2>&1`" in *-z\ ignore\|record* ) AC_MSG_RESULT(yes) @@ -2968,7 +2982,7 @@ XE_APPEND(netinstall, INSTALL_ARCH_DEP_SUBDIR) fi - install_pp="$blddir/lib-src/installexe.sh" + install_pp="$srcdir/lib-src/installexe.sh" XE_APPEND(-lshell32 -lgdi32 -luser32 -lcomdlg32 -lcomctl32 -lkernel32 -lwinspool, libs_system) test "$with_dragndrop" != no && XE_APPEND(msw, dragndrop_proto) if test "$window_system" != x11; then @@ -3570,15 +3584,27 @@ dnl Finish ensuring that we have values for the various toolkit items. dnl Not all toolkits support all widgets -dnl if Motif is available we use it for the dialog boxes. + +dnl Avoid using Motif :-( +case "$opsys" in + *linux* ) lucid_prefers_motif = "no" ;; + * ) lucid_prefers_motif = "yes" ;; +esac case "$with_menubars" in "" | "yes" | "athena" ) with_menubars="lucid" ;; esac case "$with_dialogs" in "" | "yes" | "lucid" ) - if test "$have_motif" = "yes"; then with_dialogs="motif" - elif test "$have_xaw" = "yes"; then with_dialogs="athena" - else with_dialogs=no + if test "$lucid_prefers_motif" = "yes"; then + if test "$have_motif" = "yes"; then with_dialogs="motif" + elif test "$have_xaw" = "yes"; then with_dialogs="athena" + else with_dialogs=no + fi + else + if test "$have_xaw" = "yes"; then with_dialogs="athena" + elif test "$have_motif" = "yes"; then with_dialogs="motif" + else with_dialogs=no + fi fi ;; esac case "$with_scrollbars" in "" | "yes" ) @@ -3586,9 +3612,16 @@ esac case "$with_widgets" in "yes" | "lucid") - if test "$have_motif" = "yes"; then with_widgets="motif" - elif test "$have_xaw" = "yes"; then with_widgets="athena" - else with_widgets=no + if test "$lucid_prefers_motif" = "yes"; then + if test "$have_motif" = "yes"; then with_widgets="motif" + elif test "$have_xaw" = "yes"; then with_widgets="athena" + else with_widgets=no + fi + else + if test "$have_xaw" = "yes"; then with_widgets="athena" + elif test "$have_motif" = "yes"; then with_widgets="motif" + else with_widgets=no + fi fi ;; "" ) with_widgets=no ;; @@ -3739,7 +3772,10 @@ AC_CHECKING(for XIM) AC_CHECK_LIB(X11, XOpenIM, with_xim=xlib, with_xim=no) dnl XIM + Lesstif is not (yet?) usable - if test "$have_motif $have_lesstif" = "yes no"; then + dnl Only use Motif if linking Motif anyway, or don't have xlib XIM + if test "$need_motif $have_lesstif" = "yes no"; then + AC_CHECK_LIB(Xm, XmImMbLookupString, with_xim=motif) + elif test "$have_motif $have_lesstif $with_xim" = "yes no no"; then AC_CHECK_LIB(Xm, XmImMbLookupString, with_xim=motif) fi ;; esac @@ -4150,17 +4186,25 @@ dnl Autodetect Sun native sound from SUNWaudmo package if test -z "$sound_found" -a -d "/usr/demo/SOUND"; then - sound_found=yes - XE_ADD_OBJS(sunplay.o) - if test -d "/usr/demo/SOUND/include" - then sound_cflags="-I/usr/demo/SOUND/include" - else sound_cflags="-I/usr/demo/SOUND" - fi - if test -z "$native_sound_lib" ; then - if test -r "/usr/demo/SOUND/lib/libaudio.a" - then native_sound_lib="/usr/demo/SOUND/lib/libaudio.a" - else native_sound_lib="/usr/demo/SOUND/libaudio.a" - fi + if test -d "/usr/demo/SOUND/include/multimedia"; then + sun_sound_cflags="-I/usr/demo/SOUND/include" + elif test -d "/usr/demo/SOUND/multimedia"; then + sun_sound_cflags="-I/usr/demo/SOUND" + fi + + if test -n "$native_sound_lib"; then + sun_sound_lib="$native_sound_lib" + elif test -r "/usr/demo/SOUND/lib/libaudio.a"; then + sun_sound_lib="/usr/demo/SOUND/lib/libaudio.a" + elif test -r "/usr/demo/SOUND/libaudio.a"; then + sun_sound_lib="/usr/demo/SOUND/libaudio.a" + fi + + if test -n "$sun_sound_cflags" -a -n "$sun_sound_lib"; then + native_sound_lib="$sun_sound_lib" + sound_cflags="$sun_sound_cflags" + sound_found=yes + XE_ADD_OBJS(sunplay.o) fi fi @@ -4970,6 +5014,73 @@ fi echo " Compiler: $CC $CFLAGS" +dnl Let's save some helpful-for-debugging info like compiler and libc versions.. +dnl First, see if it's gcc - the same check works everyplace... +case "$CC" in + gcc*) echo " Compiler version: `$CC --version | head -1`" + echo " Compiler specs file: `$CC -v 2>&1 | sed 's/.* \([[^ ]]\)/\1/' | head -1`" + ;; +dnl non-gcc machine-specific magic - contributions welcome + *) case "$canonical" in + *-*-aix* ) + dnl Yes, it's this ugly for AIX... + realcc=`which $CC` + dnl Might be a symlink created by replaceCset command + if test -L $realcc ; then + ccdir=`dirname $realcc` + ccprog=`/bin/ls -l $realcc | sed 's/.* \([[^ ]]\)/\1/'` + dnl This doesn't handle ../../xlc type stuff, but I've not seen one... + case $ccprog in + */*) realcc=$ccprog;; + *) realcc=$ccdir/$ccprog;; + esac + fi + lpp=`lslpp -wqc $realcc | cut -f2 -d:` + if test ! -z "$lpp" ; then + lppstr=`lslpp -Lqc $lpp` + lpplev=`echo "$lppstr" | cut -f3 -d:` + lppdesc=`echo "$lppstr" | cut -f8 -d:` + fi + if test ! -z "$lpplev" ; then + echo " Compiler version: $lpp $lpplev - $lppdesc" + else + echo " Compiler version: (unknown version)" + fi + ;; + + *-*-solaris*) + ccvers=`$CC -V 2>&1 | head -1` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + alpha*-dec-osf*) + ccvers=`$CC -V | tr '\n' ' '` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + mips-sgi-irix*) + ccvers=`$CC -version` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + dnl Intel C++ Compiler on Linux + i[[3-9]]86-pc-linux) + ccvers=`$CC -V 2>&1 | sed -n 's@^Intel.*Version @@'p` + if test ! -z "$ccvers" ; then + echo " Compiler version: $ccvers" + fi + ;; + + *) echo " Compiler version: $CC on $canonical";; + esac +esac + echo " Relocating allocator for buffers: $rel_alloc" echo " GNU version of malloc: ${GNU_MALLOC}${GNU_MALLOC_reason}" case "$ld_switch_site" in @@ -4977,6 +5088,45 @@ - Consider configuring with --pdump." ;; esac +dnl Now get the libc version - contributions welcome +case "$canonical" in + *-*-linux*) + if test -f /etc/redhat-release ; then + echo " libc: `rpm -q glibc`"; +dnl need a Debian and Suse check here... + else + echo "Need to guess glibc1/2/etc here"; + fi + ;; + + *-*-aix*) + echo " libc: bos.rte.libc `lslpp -Lqc bos.rte.libc | cut -f3 -d:`" + ;; + + *-*-solaris*) + libc=`pkginfo -l SUNWcsl | grep VERSION: | awk '{print $2}'` + echo " libc: SUNWcsl $libc" + + ;; + + mips-sgi-irix*) + echo " IRIX version: `uname -sRm`'" + ;; + + + alpha*-dec-osf*) + dnl Another ugly case + (cd /usr/.smdb.; + libc=` grep -h libc.so *.inv | awk '$9 == "f" {print $12}' | tr '\n' ','` + echo " libc: $libc" + + ) + ;; + + *) echo " libc: system-provided libc on $canonical" ;; +esac + + echo " Window System:" if test "$with_msw" = "yes"; then @@ -4998,6 +5148,9 @@ fi if test "$need_motif" = "yes" ; then echo " Compiling in support for Motif." + if test "$have_lesstif" = "yes"; then + echo " - Using LessTif implementation." + fi echo " *WARNING* Many versions of Motif are buggy, requiring workarounds." echo " You are likely to experience slow redisplay." echo " You may need to install vendor patches to Motif." diff -u -r -N xemacs-21.4.14/configure.usage xemacs-21.4.15/configure.usage --- xemacs-21.4.14/configure.usage 2003-08-17 21:43:22.000000000 -0400 +++ xemacs-21.4.15/configure.usage 2003-11-19 21:19:35.000000000 -0500 @@ -139,7 +139,7 @@ *WARNING* The Motif menubar is currently broken. --with-scrollbars=TYPE (Enum) Types: `lucid'(*), `motif', `athena', or `no'. --with-dialogs=TYPE (Enum) Types: `lucid'(*), `motif', `athena', or `no'. ---with-widgets=TYPE (Enum) Types: `lucid'(*), `motif', `athena', or `no'. +--with-widgets=TYPE (Enum) Types: `lucid', `motif', `athena', or `no'(*). --with-athena=TYPE (Enum) Link with the TYPE Athena library. Types: `xaw' [flat], `3d', `next', `95', or `xpm'. --with-dragndrop (*) Support generic drag and drop API. (EXPERIMENTAL) diff -u -r -N xemacs-21.4.14/etc/OXYMORONS xemacs-21.4.15/etc/OXYMORONS --- xemacs-21.4.14/etc/OXYMORONS 2002-12-12 01:21:13.000000000 -0500 +++ xemacs-21.4.15/etc/OXYMORONS 2004-02-02 23:49:15.000000000 -0500 @@ -36,14 +36,15 @@ 21.4.13: Rational FORTRAN 21.4.14: Reasonable Discussion 21.4.15: Security Through Obscurity -21.4.16: Social Property -21.4.17: Stable Release Maintainer -21.4.18: Standard C -21.4.19: Successful IPO -21.4.20: Sufficiently Smart Compiler -21.4.21: The Gift Economy -21.4.22: Too Much Mozart -21.4.23: UTF-8 BOM +21.4.16: Corporate Culture +21.4.17: Social Property +21.4.18: Stable Release Maintainer +21.4.19: Standard C +21.4.20: Successful IPO +21.4.21: Sufficiently Smart Compiler +21.4.22: The Gift Economy +21.4.23: Too Much Mozart +21.4.24: UTF-8 BOM N.B. Only incredibly redeeming suggestions can be accepted now. diff -u -r -N xemacs-21.4.14/etc/PACKAGES xemacs-21.4.15/etc/PACKAGES --- xemacs-21.4.14/etc/PACKAGES 2003-08-05 11:02:03.000000000 -0400 +++ xemacs-21.4.15/etc/PACKAGES 2003-11-28 20:14:01.000000000 -0500 @@ -97,6 +97,9 @@ *** emerge Another interface over GNU patch. +*** erc +ERC is an Emacs InternetRelayChat client. + *** eshell Command shell implemented entirely in Emacs Lisp. @@ -161,7 +164,8 @@ Integrated Development Environment for Java. *** liece -IRC (Internet Relay Chat) client for Emacs. +IRC (Internet Relay Chat) client for Emacs. Note, this package is +deprecated and will be removed, use riece instead. *** mail-lib Fundamental lisp files for providing email support. @@ -173,7 +177,7 @@ Messaging in an Emacs World. *** mh-e -Front end support for MH. +The XEmacs Interface to the MH Mail System. *** mine Minehunt Game. @@ -230,6 +234,9 @@ *** reftex Emacs support for LaTeX cross-references, citations. +*** riece +IRC (Internet Relay Chat) client for Emacs. + *** rmail An obsolete Emacs mailer. If you do not already use it don't start. diff -u -r -N xemacs-21.4.14/etc/package-index.LATEST.gpg xemacs-21.4.15/etc/package-index.LATEST.gpg --- xemacs-21.4.14/etc/package-index.LATEST.gpg 1969-12-31 19:00:00.000000000 -0500 +++ xemacs-21.4.15/etc/package-index.LATEST.gpg 2004-01-26 22:56:23.000000000 -0500 @@ -0,0 +1,2611 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +;; Package Index file -- Do not edit manually. +;;;@@@ +(package-get-update-base-entry (quote +(general-docs + (standards-version 1.1 + version "1.01" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "General XEmacs documentation." + filename "general-docs-1.01-pkg.tar.gz" + md5sum "06c3e4e0aeddd995f2697c91a6b8cc00" + size 1435 + provides () + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(riece + (standards-version 1.1 + version "1.12" + author-version "0.1.5" + date "2003-10-29" + build-date "2003-10-29" + maintainer "Daiki Ueno " + distribution xemacs + priority high + category "standard" + dump nil + description "IRC (Internet Relay Chat) client for Emacs." + filename "riece-1.12-pkg.tar.gz" + md5sum "8859cfde4a93a31407e29c35a35e9669" + size 106360 + provides (riece-compat riece-xemacs riece-globals riece-options riece-version riece-coding riece-complete riece-identity riece-channel riece-user riece-misc riece-layout riece-display riece-server riece-naming riece-message riece-filter riece-handle riece-000 riece-200 riece-300 riece-400 riece-500 riece-commands riece riece-ctcp riece-highlight riece-log riece-mini riece-rdcc riece-url riece-unread riece-doctor riece-alias riece-guess riece-history riece-button riece-keyword riece-menu riece-icon) + requires (xemacs-base mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(oo-browser + (standards-version 1.1 + version "1.04" + author-version "4.08" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Jake Colman " + distribution xemacs + priority high + category "standard" + dump nil + description "OO-Browser: The Multi-Language Object-Oriented Code Browser" + filename "oo-browser-1.04-pkg.tar.gz" + md5sum "72cb3bbfbe985d8989c564ca53cffe3c" + size 515713 + provides (c++-browse clos-browse eif-browse hasht hmouse-br info-browse java-brows objc-brows pyth-brows smt-browse) + requires (xemacs-base hyperbole) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(hyperbole + (standards-version 1.0 + version "1.13" + author-version "4.18" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Mats Lidell " + distribution stable + priority high + category "standard" + dump nil + description "Hyperbole: The Everyday Info Manager" + filename "hyperbole-1.13-pkg.tar.gz" + md5sum "fed416810d33560f433c4ad0bef605bc" + size 634192 + provides (hact hactypes hargs hbdata hbmap hbut hgnus hhist hib-doc-id hib-kbd hibtypes hinit hlvar hmail hmh hmoccur hmous-info hmouse-drv hmouse-key hmouse-mod hmouse-tag hpath hrmail hsite hsmail hsys-w3 hsys-wais htz hui-menu hui-mini hui-mouse hui-window hui-xe-but hui hvar hversion hvm hypb hyperbole set wconfig wrolo-logic wrolo-menu wrolo) + requires (xemacs-base mail-lib calendar vm text-modes gnus mh-e rmail apel tm sh-script net-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ecb + (standards-version 1.1 + version "1.13" + author-version "1.96" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Klaus Berndl " + distribution xemacs + priority low + category "standard" + dump nil + description "Emacs source code browser." + filename "ecb-1.13-pkg.tar.gz" + md5sum "dbbc4f68db8f2f294b89f0ee11ae6156" + size 525836 + provides (ecb-buffertab ecb-compilation ecb-create-layout ecb-cycle ecb ecb-eshell ecb-examples ecb-face ecb-help ecb-layout ecb-layout-defs ecb-mode-line ecb-navigate ecb-speedbar ecb-tod ecb-autogen ecb-jde ecb-upgrade ecb-util ecb-winman-support silentcomp tree-buffer) + requires (xemacs-base semantic eieio fsf-compat edit-utils jde mail-lib eshell ediff xemacs-devel speedbar c-support) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(pgg + (standards-version 1.1 + version "1.04" + author-version "0.1" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Simon Josefsson " + distribution xemacs + priority low + category "standard" + dump nil + description "Emacs interface to various PGP implementations." + filename "pgg-1.04-pkg.tar.gz" + md5sum "8f4d77a0e99edbd3040c8d3988109ee8" + size 31307 + provides (pgg pgg-def pgg-parse pgg-gpg pgg-pgp pgg-pgp5) + requires (xemacs-base fsf-compat edebug) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(perl-modes + (standards-version 1.1 + version "1.05" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Perl support." + filename "perl-modes-1.05-pkg.tar.gz" + md5sum "cbfc241502bb708e878bcb2d587a78b1" + size 161184 + provides (cperl-mode perl-mode) + requires (xemacs-base ispell ps-print edit-utils fsf-compat) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(python-modes + (standards-version 1.1 + version "1.03" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Python support." + filename "python-modes-1.03-pkg.tar.gz" + md5sum "537b318e5901cfc95ba7dfcce32d24bf" + size 82105 + provides (pydoc python-mode) + requires (xemacs-base mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ruby-modes + (standards-version 1.1 + version "1.02" + author-version "1.6.8" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Ruby support." + filename "ruby-modes-1.02-pkg.tar.gz" + md5sum "d2a1ca596592bafba72c76158d26747b" + size 21889 + provides (inf-ruby ruby-mode rubydb) + requires (xemacs-base debug) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(fortran-modes + (standards-version 1.1 + version "1.03" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Fortran support." + filename "fortran-modes-1.03-pkg.tar.gz" + md5sum "413d2f5ea1497c29b436fee52073563b" + size 66719 + provides (f90 fortran) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(psgml-dtds + (standards-version 1.1 + version "1.03" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Deprecated collection of DTDs for psgml." + filename "psgml-dtds-1.03-pkg.tar.gz" + md5sum "6d2d68e928a540581ef564d1111fcbf2" + size 367476 + provides () + requires (xemacs-base psgml edit-utils mail-lib fsf-compat eterm sh-script) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(docbookide + (standards-version 1.1 + version "0.07" + author-version "0.1" + date "2003-10-28" + build-date "2003-10-28" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "DocBook editing support." + filename "docbookide-0.07-pkg.tar.gz" + md5sum "2e83cb54d4c0d9fd4b22a81d8792e9e6" + size 32091 + provides (dbide-abbrev dbide-data dbide-font dbide-process docbookide) + requires (xemacs-base ispell mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ecrypto + (standards-version 1.1 + version "0.14" + author-version "2.0" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Simon Josefsson " + distribution xemacs + priority low + category "standard" + dump nil + description "Crypto functionality in Emacs Lisp." + filename "ecrypto-0.14-pkg.tar.gz" + md5sum "59207e5f5a5300ccf0d21f27b018de91" + size 68741 + provides (ascii-armor blowfish des hex-util md4 md5-dl md5-el md5 paranoid rander rc16 rijndael sha1-dl sha1-el sha1) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ocaml + (standards-version 1.1 + version "0.05" + author-version "3.06" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Objective Caml editing support." + filename "ocaml-0.05-pkg.tar.gz" + md5sum "2ca033386cade4dbdb05abe2e6f324f4" + size 64887 + provides (caml-compat camldebug caml caml-font caml-help inf-caml) + requires (xemacs-base fsf-compat) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sasl + (standards-version 1.1 + version "1.14" + author-version "1.14.4" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Simon Josefsson " + distribution xemacs + priority low + category "standard" + dump nil + description "Simple Authentication and Security Layer (SASL) library." + filename "sasl-1.14-pkg.tar.gz" + md5sum "a00a2f0e7e6f1614ae95cdbef50e333e" + size 27045 + provides (hmac-def hmac-md5 hmac-sha1 ntlm sasl sasl-cram sasl-digest sasl-ntlm sasl-plain sasl-login sasl-anonymous) + requires (ecrypto) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sml-mode + (standards-version 1.1 + version "0.10" + author-version "3.9.5" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "SML editing support." + filename "sml-mode-0.10-pkg.tar.gz" + md5sum "87914cf428610799a98815b17393f6e0" + size 81763 + provides (sml-compat sml-defs sml-mode sml-move sml-proc sml-util) + requires (xemacs-base edebug fsf-compat) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ess + (standards-version 1.1 + version "1.06" + author-version "5.1.21" + date "2003-11-10" + build-date "2003-11-10" + maintainer "A.J. Rossini " + distribution xemacs + priority medium + category "standard" + dump nil + description "ESS: Emacs Speaks Statistics." + filename "ess-1.06-pkg.tar.gz" + md5sum "46e105b2fd715790f6358d9f637cdf32" + size 445788 + provides (ess-batch ess-comp ess-cust ess-dump ess-emcs ess-font-lock ess-help ess-inf ess-iw32 ess-latex-mode ess-menu ess-mode ess-mous ess-noweb ess-site ess-sysdp ess-utils ess-vars ess essa-r essa-sas essd-arc essd-els essd-r essd-omg essd-r essd-s3 essd-s4 essd-sas essd-sp3 essd-sp4 essd-sp5 essd-sp6 essd-sta essd-vst essd-xls essddr essdsp6w essl-bug essl-lsp essl-omg essl-py essl-s essl-sas essl-sta make-regexp mouseme msdos noweb-font-lock-mode noweb-mode) + requires (xemacs-base mail-lib fsf-compat edit-utils speedbar sh-script eterm) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(haskell-mode + (standards-version 1.1 + version "1.06" + author-version "1.44" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Haskell editing support." + filename "haskell-mode-1.06-pkg.tar.gz" + md5sum "75c3dcb6fbe0a8824c865d8b989866cc" + size 94315 + provides (haskell-decl-scan haskell-doc haskell-font-lock haskell-indent haskell-mode haskell-simple-indent) + requires (dired mail-lib xemacs-base edit-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(xslide + (standards-version 1.1 + version "1.09" + author-version "0.2.2" + date "2003-10-28" + build-date "2003-10-28" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "XSL editing support." + filename "xslide-1.09-pkg.tar.gz" + md5sum "998f787ea80d98cdd7ca06c25ae96647" + size 39199 + provides (xslide-abbrev xslide-data xslide-font xslide-process xslide) + requires (ispell mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(liece + (standards-version 1.1 + version "1.12" + author-version "1.4.9" + date "2003-04-22" + build-date "2003-04-22" + maintainer "Daiki Ueno " + distribution xemacs + priority high + category "standard" + dump nil + description "IRC (Internet Relay Chat) client for Emacs." + filename "liece-1.12-pkg.tar.gz" + md5sum "c7f2aab45f8ada9398d4b0807e80433a" + size 199275 + provides (liece-xemacs gettext liece-clfns liece-handler liece-compat liece-version liece-vars liece-globals liece-inlines liece-filter liece-coding liece-dcc liece-menu liece-000 liece-200 liece-300 liece-400 liece-500 liece-nick liece-channel liece-commands liece-ctcp liece-q-el liece-message liece-handle liece-hilit liece-intl liece-mail liece-minibuf liece-misc liece-tcp liece-url liece-x-face liece-window liece) + requires (apel mail-lib fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(latin-unity + (standards-version 1.1 + version "1.09" + author-version "1.09" + date "2003-11-09" + build-date "2003-11-09" + maintainer "Stephen J. Turnbull " + distribution mule + priority high + category "mule" + dump nil + description "MULE: find single ISO 8859 character set to encode a buffer." + filename "latin-unity-1.09-pkg.tar.gz" + md5sum "83b7fd603ad7cd5d9c459a0035501cac" + size 106267 + provides (latin-unity latin-unity-tables latin-unity-utils) + requires (mule-base mule-ucs leim fsf-compat dired) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mmm-mode + (standards-version 1.1 + version "1.01" + author-version "0.4.7" + date "2003-10-29" + build-date "2003-10-29" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Multiple major modes in a single buffer" + filename "mmm-mode-1.01-pkg.tar.gz" + md5sum "28cf0136d0d8e59e74a464074a98ef4b" + size 175927 + provides (mmm-auto mmm-class mmm-cmds mmm-compat mmm-mason mmm-mode mmm-region mmm-rpm mmm-sample mmm-univ mmm-utils mmm-vars) + requires (xemacs-base fsf-compat ) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ibuffer + (standards-version 1.1 + version "1.09" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "John Paul Wallington " + distribution xemacs + priority medium + category "standard" + dump nil + description "Advanced replacement for buffer-menu" + filename "ibuffer-1.09-pkg.tar.gz" + md5sum "5132ee34ac4640fdb7a53706ee928e33" + size 89926 + provides (ibuf-ext ibuf-macs ibuffer) + requires (ibuffer xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(xemacs-base + (standards-version 1.1 + version "1.82" + author-version "No-Upstream-Ver" + date "2003-10-29" + build-date "2003-10-29" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "Fundamental XEmacs support, you almost certainly need this." + filename "xemacs-base-1.82-pkg.tar.gz" + md5sum "7ba84839d26de61e4cb62741531d59ba" + size 472771 + provides (add-log advice-preload advice annotations assoc case-table chistory comint-xemacs comint compile debug ebuff-menu echistory edmacro ehelp electric enriched env facemenu ffap helper imenu iso-syntax macros novice outline passwd pp regexp-opt regi ring shell skeleton sort thing time-stamp timezone tq xbm-button xpm-button) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(tramp + (standards-version 1.1 + version "1.16" + author-version "2.0.35" + date "2003-07-21" + build-date "2003-07-21" + maintainer "Kai Großjohann " + distribution xemacs + priority low + category "standard" + dump nil + description "Remote shell-based file editing." + filename "tramp-1.16-pkg.tar.gz" + md5sum "ec5a21c4462d48ebe8dc01ea0e32373c" + size 251091 + provides (tramp tramp-efs tramp-ftp tramp-smb tramp-util tramp-uu + tramp-vc trampcache) + requires (tramp xemacs-base vc fsf-compat efs dired mail-lib gnus ediff) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(text-modes + (standards-version 1.1 + version "1.71" + author-version "No-Upstream-Ver" + date "2003-11-13" + build-date "2003-11-13" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "Miscellaneous support for editing text files." + filename "text-modes-1.71-pkg.tar.gz" + md5sum "39be167962dc1a547a13f8bb1788327f" + size 377506 + provides (ansi-color autoinsert crontab-edit desktop-entry-mode filladapt flyspell folding fold-isearch hexl htmlize image-mode iso-acc iso-ascii iso-cvt iso-insert iso-swed rtf-support swedish tabify whitespace-mode winmgr-mode xpm-mode xrdb-mode apache-mode po-mode po-compat css-mode) + requires (ispell fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(pcl-cvs + (standards-version 1.1 + version "1.65" + author-version "R-2_9_9" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "CVS frontend." + filename "pcl-cvs-1.65-pkg.tar.gz" + md5sum "53b8cbd4d0b7709cfaf9d51e11888324" + size 161016 + provides (cvs-compat cvs-edit cvs-log cvs-status easy-mmode pcl-cvs-defs pcl-cvs-info pcl-cvs-parse pcl-cvs-util pcl-cvs) + requires (xemacs-base elib vc dired edebug ediff edit-utils mail-lib prog-modes) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mail-lib + (standards-version 1.1 + version "1.63" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Simon Josefsson " + distribution xemacs + priority medium + category "standard" + dump nil + description "Fundamental lisp files for providing email support." + filename "mail-lib-1.63-pkg.tar.gz" + md5sum "99b3f341e8c29ad2dc3fec5196e32549" + size 198134 + provides (base64 browse-url-xemacs browse-url highlight-headers mail-abbrevs mail-extr mail-utils mailheader netrc pop3 reporter rfc2104 rfc822 rmail rmail-mini rmailout sendmail smtpmail starttls tls) + requires (eterm xemacs-base fsf-compat sh-script ecrypto) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(jde + (standards-version 1.1 + version "1.46" + author-version "2.3.2" + date "2003-10-08" + build-date "2003-10-08" + maintainer "Andy Piper " + distribution xemacs + priority medium + category "standard" + dump nil + description "Integrated Development Environment for Java." + filename "jde-1.46-pkg.tar.gz" + md5sum "60f5d299a53be811f6ef6006f2566c20" + size 2403395 + provides (beanshell efc jde-ant jde-bug jde-checkstyle jde-compat jde-compile jde-complete jde-db jde-dbo jde-dbs jde-ejb jde-gen jde-help jde-imenu jde-import jde-java-font-lock jde-java-grammar jde-javadoc-gen jde-javadoc jde-jdb jde-make jde-open-source jde-package jde-parse-class jde-parse jde-run jde-setnu jde-stat jde-util jde-which-method jde-widgets jde-wiz jde-xref jde tree-widget) + requires (jde cc-mode semantic debug speedbar edit-utils eterm mail-lib xemacs-base xemacs-devel eieio elib sh-script fsf-compat) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(fsf-compat + (standards-version 1.1 + version "1.13" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "FSF Emacs compatibility files." + filename "fsf-compat-1.13-pkg.tar.gz" + md5sum "270a9deea6166bb38ac00f6191c7e8c0" + size 21687 + provides (overlay thingatpt timer x-popup-menu goto-addr) + requires (xemacs-base) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(edit-utils + (standards-version 1.1 + version "2.10" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "Miscellaneous editor extensions, you probably need this." + filename "edit-utils-2.10-pkg.tar.gz" + md5sum "8d3c77a3ae8fb443a608a148e32e0d48" + size 925330 + provides (abbrevlist after-save-commands atomic-extents avoid backup-dir balloon-help big-menubar blink-cursor blink-paren bookmark compare-w completion dabbrev desktop detached-minibuf edit-toolbar fast-lock file-part floating-toolbar flow-ctrl foldout func-menu hippie-exp icomplete id-select info-look iswitchb lazy-lock lazy-shot live-icon makesum man mic-paren paren mode-motion+ outl-mouse outln-18 page-ext blink-paren paren permanent-buffers popper power-macros recent-files redo reportmail resume rsz-minibuf saveconf savehist saveplace scroll-in-place setnu shell-font tempo toolbar-utils tree-menu uniquify vertical-mode where-was-i-db winring autorevert align allout outline narrow-stack highline) + requires (xemacs-base xemacs-devel fsf-compat dired mail-lib) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(skk + (standards-version 1.1 + version "1.23" + author-version "10.62a" + date "2002-09-25" + build-date "2002-09-25" + maintainer "XEmacs Development Team " + distribution mule + priority medium + category "mule" + dump nil + description "MULE: Japanese Language Input Method." + filename "skk-1.23-pkg.tar.gz" + md5sum "dc35f20896a56c8cf2e7ba16b15e453b" + size 1506691 + provides (skk-auto skk-comp skk-cursor skk-develop skk-foreword skk-gadget skk-isearch skk-kakasi skk-kcode skk-leim skk-look skk-num skk-obsolete skk-server skk-tut skk-vars skk-viper skk vip) + requires (viper mule-base elib xemacs-base apel) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ps-print + (standards-version 1.1 + version "1.09" + author-version "6.5.6" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Printing functions and utilities" + filename "ps-print-1.09-pkg.tar.gz" + md5sum "9055fe7244e253e2a12cc7e4d69df041" + size 155737 + provides (lpr ps-bdf ps-mule ps-print) + requires (text-modes) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sieve + (standards-version 1.1 + version "1.14" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Simon Josefsson " + distribution xemacs + priority low + category "standard" + dump nil + description "Manage Sieve email filtering scripts." + filename "sieve-1.14-pkg.tar.gz" + md5sum "6a9234ad3e59c485869db92a3637d91f" + size 25677 + provides (sieve sieve-mode sieve-manage) + requires (xemacs-base mail-lib cc-mode sasl) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mule-ucs + (standards-version 1.1 + version "1.05" + author-version "0.84" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Stephen J. Turnbull " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Extended coding systems (including Unicode) for XEmacs." + filename "mule-ucs-1.05-pkg.tar.gz" + md5sum "772c06a697d0b3b4d7b78e8df76c019c" + size 1314530 + provides (mccl-font mucs-ccl mucs-error mucs-type mucs mule-uni tae tbl-mg trans-util txt-tbl un-data un-define un-supple un-tools un-trbase unicode unidata utf u-cns-1 u-cns-2 u-cns-3 u-cns-4 u-cns-5 u-cns-6 u-cns-7 uascii ubig5 uetiopic ugb2312 uipa uiscii uiso8859-1 uiso8859-14 uiso8859-15 uiso8859-2 uiso8859-3 uiso8859-4 uiso8859-5 uiso8859-6 uiso8859-7 uiso8859-8 uiso8859-9 ujisx0201 ujisx0208 ujisx0212 uksc5601 usisheng usupple utibetan utis620 uviscii) + requires (mule-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(clearcase + (standards-version 1.0 + version "1.08" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Michael Diers " + distribution xemacs + priority low + category "standard" + dump nil + description "New Clearcase Version Control for XEmacs (UNIX, Windows)." + filename "clearcase-1.08-pkg.tar.gz" + md5sum "6fedc7464137eae08c25517276f8a7ab" + size 94543 + provides (clearcase) + requires (dired fsf-compat mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(dictionary + (standards-version 1.1 + version "1.12" + author-version "1.8" + date "2003-06-22" + build-date "2003-06-22" + maintainer "Torsten Hilbrich " + distribution xemacs + priority low + category "standard" + dump nil + description "Interface to RFC2229 dictionary servers." + filename "dictionary-1.12-pkg.tar.gz" + md5sum "717517bbad4e241f18941fd6c289b868" + size 39658 + provides (dictionary connection link) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(build + (standards-version 1.0 + version "1.14" + author-version "2.02" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Adrian Aichner " + distribution stable + priority low + category "standard" + dump nil + description "Build XEmacs from within (UNIX, Windows)." + filename "build-1.14-pkg.tar.gz" + md5sum "927263daa5b6d8097b916f0be5887a62" + size 49484 + provides (build) + requires (xemacs-base pcl-cvs dired w3 prog-modes) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(xslt-process + (standards-version 1.0 + version "1.11" + author-version "1.2.1" + date "2002-10-08" + build-date "2002-10-08" + maintainer "Ovidiu Predescu " + distribution xemacs + priority medium + category "standard" + dump nil + description "XSLT processing support." + filename "xslt-process-1.11-pkg.tar.gz" + md5sum "30273cbe2e90ae703ea410879412e68b" + size 199873 + provides (xslt-process) + requires (jde cc-mode semantic debug speedbar edit-utils eterm mail-lib xemacs-base elib eieio sh-script fsf-compat xemacs-devel) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(eieio + (standards-version 1.1 + version "1.05" + author-version "0.17" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Eric Ludlam " + distribution xemacs + priority low + category "standard" + dump nil + description "Enhanced Implementation of Emacs Interpreted Objects" + filename "eieio-1.05-pkg.tar.gz" + md5sum "b31f8f71fc5afa41196954f04f955654" + size 165803 + provides (call-tree chart compare-strings eieio-base eieio-comp eieio-custom eieio-doc eieio-opt eieio-speedbar eieio-tests eieio linemark tree) + requires (speedbar xemacs-base edebug) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(egg-its + (standards-version 1.1 + version "1.27" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Wnn (4.2 and 6) support. SJ3 support." + filename "egg-its-1.27-pkg.tar.gz" + md5sum "6027d90327043f918d8a4ea3143ae7d2" + size 261339 + provides (egg-cnpinyin egg-cnzhuyin egg-cwnn-leim egg-jisx0201 egg-jsymbol egg-kwnn-leim egg-leim egg-sj3-client egg-sj3-leim egg-sj3 egg-wnn egg) + requires (leim mule-base fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(edict + (standards-version 1.1 + version "1.16" + author-version "0.9.9" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Stephen J. Turnbull " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Lisp Interface to EDICT, Kanji Dictionary." + filename "edict-1.16-pkg.tar.gz" + md5sum "406e55fda150ec0ea22b79580279be95" + size 96111 + provides (dui-registry dui edict-edit edict-english edict-japanese edict-morphology edict-test edict ts-mode) + requires (mule-base xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(lookup + (standards-version 1.1 + version "1.14" + author-version "1.0" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Dictionary support" + filename "lookup-1.14-pkg.tar.gz" + md5sum "f48776563d7fbd0852ad73ac9c513260" + size 225996 + provides (evi-mule evi lookup-content lookup-defs lookup-entry lookup-select lookup-package lookup-select lookup-types lookup-utils lookup-vars lookup-vse lookup ndcookie ndeb ndic ndict ndkks ndmisc ndnmz ndspell ndsrd ndtp sdicf stem) + requires (mule-base cookie lookup) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(leim + (standards-version 1.1 + version "1.22" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution mule + priority medium + category "mule" + dump nil + description "MULE: Quail. All non-English and non-Japanese language support." + filename "leim-1.22-pkg.tar.gz" + md5sum "942fbcd4d56eb59529bbd15c3b6c0b3b" + size 1708319 + provides () + requires (leim mule-base fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(locale + (standards-version 1.1 + version "1.21" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Localized menubars and localized splash screens." + filename "locale-1.21-pkg.tar.gz" + md5sum "2256243bb8cdd282af7b40bc2cf30018" + size 36961 + provides () + requires (mule-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mule-base + (standards-version 1.1 + version "1.44" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution mule + priority high + category "mule" + dump nil + description "MULE: Basic Mule support, required for building with Mule." + filename "mule-base-1.44-pkg.tar.gz" + md5sum "9eaa93208008617bd8f0d34448dcfaa3" + size 444749 + provides (canna-leim canna char-table china-util cyril-util isearch-ext japan-util ccl can-n-egg mule-help) + requires (fsf-compat xemacs-base apel) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(strokes + (standards-version 1.1 + version "1.10" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Mouse enhancement utility." + filename "strokes-1.10-pkg.tar.gz" + md5sum "946a6e0bb3e9384a94a79ecdffdd85d8" + size 43728 + provides (strokes) + requires (text-modes edit-utils mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(time + (standards-version 1.1 + version "1.14" + author-version "1.17" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Display time & date on the modeline." + filename "time-1.14-pkg.tar.gz" + md5sum "8956073a18694a8ad91a52c7374c3d66" + size 20431 + provides (time) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(slider + (standards-version 1.1 + version "1.15" + author-version "0.3x1" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "User interface tool." + filename "slider-1.15-pkg.tar.gz" + md5sum "00bb43e4f3997c0c493cb7f29a75494b" + size 12516 + provides (slider color-selector) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sgml + (standards-version 1.1 + version "1.10" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "SGML/Linuxdoc-SGML editing." + filename "sgml-1.10-pkg.tar.gz" + md5sum "ab80262877e3547dfb97e80a0a778e09" + size 27462 + provides (sgml linuxdoc-sgml) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(psgml + (standards-version 1.1 + version "1.41" + author-version "1.3.1" + date "2003-08-29" + build-date "2003-08-29" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Validated HTML/SGML editing." + filename "psgml-1.41-pkg.tar.gz" + md5sum "33baca4b85d3d9c48df682b748c9a273" + size 301000 + provides (iso-sgml psgml-api psgml-charent psgml-debug psgml-dtd psgml-edit psgml-fs psgml-html psgml-info psgml-parse psgml-sysdep psgml-xemacs psgml sgml-mode) + requires (xemacs-base edit-utils edebug xemacs-devel mail-lib fsf-compat eterm sh-script ps-print) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(pc + (standards-version 1.1 + version "1.26" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "PC style interface emulation." + filename "pc-1.26-pkg.tar.gz" + md5sum "47189d077b363012c4b17f527eef2ec7" + size 17611 + provides (delbs fusion pc-select pending-del s-region) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ispell + (standards-version 1.1 + version "1.26" + author-version "3.3" + date "2003-11-02" + build-date "2003-11-02" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Spell-checking with GNU ispell." + filename "ispell-1.26-pkg.tar.gz" + md5sum "85a9da0fe8ed41199388b5f41a0f7769" + size 72869 + provides (ispell) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(hm--html-menus + (standards-version 1.1 + version "1.23" + author-version "5.9" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "HTML editing." + filename "hm--html-menus-1.23-pkg.tar.gz" + md5sum "c625e8070a7abfed6fb1f13d04a38e51" + size 179091 + provides (adapt hm--date hm--html-configuration hm--html-drag-and-drop hm--html-indentation hm--html-keys hm--html-menu hm--html-mode hm--html-not-standard hm--html html-view internal-drag-and-drop tmpl-minor-mode) + requires (dired xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(frame-icon + (standards-version 1.1 + version "1.11" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Set up mode-specific icons for each frame under XEmacs" + filename "frame-icon-1.11-pkg.tar.gz" + md5sum "6fbd58bc7f37328aaf31b420c9a2891f" + size 33800 + provides (forms forms-mode) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(forms + (standards-version 1.1 + version "1.15" + author-version "2.37" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Forms editing support (obsolete, use Widget instead)." + filename "forms-1.15-pkg.tar.gz" + md5sum "5f5cc842399040018bab20f776cf1cf8" + size 48747 + provides (forms forms-mode) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(calendar + (standards-version 1.1 + version "1.22" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Calendar and diary support." + filename "calendar-1.22-pkg.tar.gz" + md5sum "c9f0bdbcb3cbbb9eff338e4edd9d7f95" + size 253996 + provides (appt cal-china cal-coptic cal-dst cal-french cal-hebrew cal-islam cal-iso cal-japanese cal-julian cal-mayan cal-move cal-persia cal-tex cal-x cal-xemacs calendar diary-lib holidays lunar solar) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(calc + (standards-version 1.1 + version "1.24" + author-version "2.02fX3" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Emacs calculator" + filename "calc-1.24-pkg.tar.gz" + md5sum "61fa56abe04492e448a8549b5978ca3a" + size 1600141 + provides (calc-ext calc-macs calc) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(speedbar + (standards-version 1.1 + version "1.27" + author-version "0.14beta4" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Eric M. Ludlam " + distribution xemacs + priority low + category "standard" + dump nil + description "Provides a separate frame with convenient references." + filename "speedbar-1.27-pkg.tar.gz" + md5sum "4df8d109364493dca814ef7429d560d2" + size 163245 + provides (bigclock dframe rpm sb-ant sb-gud sb-html sb-image sb-info sb-rmail sb-texinfo sb-w3 speedbar) + requires (xemacs-base edebug) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(pcomplete + (standards-version 1.1 + version "1.03" + author-version "1.1.6" + date "2003-10-31" + build-date "2003-10-31" + maintainer "John Wiegley " + distribution xemacs + priority medium + category "standard" + dump nil + description "Provides programmatic completion." + filename "pcomplete-1.03-pkg.tar.gz" + md5sum "43bad91be873dd6ae2f9483e90c42226" + size 37443 + provides (pcomplete) + requires (sh-script xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(eshell + (standards-version 1.1 + version "1.06" + author-version "2.4.1" + date "2003-10-31" + build-date "2003-10-31" + maintainer "John Wiegley " + distribution xemacs + priority medium + category "standard" + dump nil + description "Command shell implemented entirely in Emacs Lisp" + filename "eshell-1.06-pkg.tar.gz" + md5sum "737f4d5caed7ffe8cb987f0e2459d6e8" + size 232041 + provides (em-alias em-banner em-basic em-cmpl em-dirs em-glob em-hist em-ls em-pred em-prompt em-rebind em-script em-smart em-term em-unix em-xtra esh-arg esh-cmd esh-ext esh-io esh-maint esh-mode esh-module esh-opt esh-proc esh-test esh-toggle esh-util esh-var eshell) + requires (xemacs-base eterm) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(view-process + (standards-version 1.1 + version "1.13" + author-version "2.4" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "A Unix process browsing tool." + filename "view-process-1.13-pkg.tar.gz" + md5sum "05eca7ec61259b47f2a741fc30dcc65f" + size 60814 + provides (view-process-mode) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(os-utils + (standards-version 1.1 + version "1.34" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Miscellaneous O/S utilities." + filename "os-utils-1.34-pkg.tar.gz" + md5sum "98fa67e0d1b89febd16bfc952d552171" + size 225849 + provides (archive-mode background crypt++ crypt ftelnet inf-lisp jka-compr mchat rlogin ssh tar-mode telnet terminal uncompress) + requires (xemacs-base) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ilisp + (standards-version 1.1 + version "1.33" + author-version "5.12.0" + date "2003-10-31" + build-date "2003-10-31" + maintainer "ilisp Maintainers " + distribution xemacs + priority low + category "standard" + dump nil + description "Front-end for Inferior Lisp." + filename "ilisp-1.33-pkg.tar.gz" + md5sum "a0edbe80726e199f3cfc7a367c3fd772" + size 344245 + provides (bridge comint-ipc completer ilcompat compat-fsf18 compat-fsf-19 compat-fsf-20 ilisp-chs ilisp-cl-easy-menu ilisp-ext ilisp-lw ilisp-key ilisp-menu ilisp-mnb ilisp-scheme-easy-menu ilisp il-luc19 il-luc19) + requires (xemacs-base mail-lib fsf-compat eterm sh-script) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(igrep + (standards-version 1.1 + version "1.12" + author-version "2.95" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Enhanced front-end for Grep." + filename "igrep-1.12-pkg.tar.gz" + md5sum "a46e749b903ad526dad1a898496e9812" + size 17316 + provides (igrep) + requires (dired xemacs-base efs) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(eterm + (standards-version 1.1 + version "1.15" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Terminal emulation." + filename "eterm-1.15-pkg.tar.gz" + md5sum "4821611600abfb6f7e6d2d91b361e5dc" + size 109135 + provides (eterm) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(viper + (standards-version 1.1 + version "1.37" + author-version "3.09" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Michael Kifer " + distribution xemacs + priority low + category "standard" + dump nil + description "VI emulation support." + filename "viper-1.37-pkg.tar.gz" + md5sum "5bd6157ea98d1cc9399e91eb3b684c8c" + size 327719 + provides (viper-cmd viper-ex viper-init viper-keym viper-macs viper-mous viper-util viper) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(tpu + (standards-version 1.1 + version "1.14" + author-version "4.2X" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Kevin Oberman " + distribution xemacs + priority medium + category "standard" + dump nil + description "DEC EDIT/TPU support." + filename "tpu-1.14-pkg.tar.gz" + md5sum "f3f5ef913e958e5532a2a682288eac05" + size 59529 + provides (tpu) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(textools + (standards-version 1.1 + version "1.15" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Miscellaneous TeX support." + filename "textools-1.15-pkg.tar.gz" + md5sum "43d33c2e35569a434e7787e7ded2eade" + size 79966 + provides (bib-mode bibtex refer-to-bibtex) + requires (xemacs-base) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(texinfo + (standards-version 1.1 + version "1.25" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "XEmacs TeXinfo support." + filename "texinfo-1.25-pkg.tar.gz" + md5sum "a2755f74e1f4c76ba36d844abc718d3a" + size 133884 + provides (makeinfo tex-mode texinfmt texinfo texnfo-tex texnfo-upd) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(reftex + (standards-version 1.1 + version "1.33" + author-version "4.21" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Carsten Dominik " + distribution xemacs + priority medium + category "standard" + dump nil + description "Emacs support for LaTeX cross-references, citations.." + filename "reftex-1.33-pkg.tar.gz" + md5sum "4d9a603199ad55c5d3f3cd31413a56de" + size 352053 + provides (reftex-auc reftex-cite reftex-dcr reftex-vcr reftex-global reftex-index reftex-parse reftex-ref reftex-sel reftex-toc reftex-vars reftex) + requires (fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(edt + (standards-version 1.1 + version "1.13" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "DEC EDIT/EDT emulation." + filename "edt-1.13-pkg.tar.gz" + md5sum "1ca337b8b41799394068717d8d716516" + size 62754 + provides (edt) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(crisp + (standards-version 1.1 + version "1.14" + author-version "1.34" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Crisp/Brief emulation." + filename "crisp-1.14-pkg.tar.gz" + md5sum "ba1bbc29153b1849e71d123b9f2021b1" + size 10361 + provides (crisp scroll-lock) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(auctex + (standards-version 1.1 + version "1.35" + author-version "11.13" + date "2003-01-03" + build-date "2003-01-03" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Basic TeX/LaTeX support." + filename "auctex-1.35-pkg.tar.gz" + md5sum "168e82155e152dab8c7c913bc9a4788b" + size 406466 + provides (auc-old auc-tex bib-cite font-latex latex multi-prompt tex-buf tex-info tex-jp tex-mik tex-site tex texmathp) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(vhdl + (standards-version 1.1 + version "1.18" + author-version "3.31.20" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Support for VHDL." + filename "vhdl-1.18-pkg.tar.gz" + md5sum "6a38f9e4428754114593b94089c71943" + size 273202 + provides (vhdl-mode) + requires (xemacs-base edit-utils c-support speedbar ps-print os-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(x-symbol + (standards-version 1.1 + version "1.07" + author-version "4.5.1" + date "2003-10-26" + build-date "2003-10-26" + maintainer "Steve Youngs " + distribution xemacs + priority high + category "standard" + dump nil + description "Semi WYSIWYG for LaTeX, HTML, etc, using additional fonts." + filename "x-symbol-1.07-pkg.tar.gz" + md5sum "c4a1cfc1318d5eb87eb186f0972abad6" + size 679781 + provides (x-symbol-bib x-symbol-hooks x-symbol-image x-symbol-macs x-symbol-mule x-symbol-nomule x-symbol-sgml x-symbol-tex x-symbol-texi x-symbol-vars x-symbol-xmacs x-symbol) + requires (x-symbol xemacs-base auctex mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(vc + (standards-version 1.1 + version "1.38" + author-version "No-Upstream-Ver" + date "2003-10-27" + build-date "2003-10-27" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Version Control for Free systems." + filename "vc-1.38-pkg.tar.gz" + md5sum "b19fa9b253ec9335829c3289ea1b046b" + size 93835 + provides (vc vc-hooks) + requires (dired xemacs-base vc mail-lib ediff) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(vc-cc + (standards-version 1.1 + version "1.22" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Version Control for ClearCase (UnFree) systems." + filename "vc-cc-1.22-pkg.tar.gz" + md5sum "ee4ce6853773d36dd92b53ce2513fd73" + size 95028 + provides (vc-cc vc-cc-hooks) + requires (dired xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sh-script + (standards-version 1.1 + version "1.18" + author-version "2.0e" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Support for editing shell scripts." + filename "sh-script-1.18-pkg.tar.gz" + md5sum "4a0e2de6d1006c987dfd9e861b8562cd" + size 37055 + provides (sh-script executable) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(scheme + (standards-version 1.1 + version "1.14" + author-version "No-Upstream-Ver" + date "2003-10-28" + build-date "2003-10-28" + maintainer "Karl M. Hegbloom " + distribution xemacs + priority low + category "standard" + dump nil + description "Front-end support for Inferior Scheme." + filename "scheme-1.14-pkg.tar.gz" + md5sum "0d64efd541819d9ba12cdafa9036edc7" + size 37770 + provides (scheme xscheme cmuscheme cmuscheme48) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(prog-modes + (standards-version 1.1 + version "1.91" + author-version "No-Upstream-Ver" + date "2003-10-29" + build-date "2003-10-29" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Support for various programming languages." + filename "prog-modes-1.91-pkg.tar.gz" + md5sum "b0203d7e022fdf730845ffbceaf41bf0" + size 715961 + provides (autoconf-mode awk-mode c-mode cvs diff-mode eiffel-mode icon javascript-mode ksh-mode m4-mode make-mode makefile mode-compile mode-compile-kill modula2 p4 php-mode postscript rexx-mode rpm-spec-mode simula-mode sql tcl teco uil-mode verilog-mode) + requires (mail-lib xemacs-devel xemacs-base cc-mode fsf-compat edit-utils ediff emerge efs vc speedbar dired ilisp sh-script) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(idlwave + (standards-version 1.1 + version "1.31" + author-version "5.1" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Carsten Dominik " + distribution xemacs + priority medium + category "standard" + dump nil + description "Editing and Shell mode for the Interactive Data Language" + filename "idlwave-1.31-pkg.tar.gz" + md5sum "c5e8e00757efddd5d83d9acb31247102" + size 520952 + provides (idlw-rinfo idlwave-rinfo idlw-shell idlwave-shell idlw-toolbar idlwave-toolbar idlwave) + requires (fsf-compat xemacs-base mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(emerge + (standards-version 1.1 + version "1.11" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Another interface over GNU patch." + filename "emerge-1.11-pkg.tar.gz" + md5sum "f47b98cdf120c123bee14ff9d1ff0862" + size 61367 + provides (emerge) + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ediff + (standards-version 1.1 + version "1.49" + author-version "2.75" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Michael Kifer " + distribution xemacs + priority medium + category "standard" + dump nil + description "Interface over GNU patch." + filename "ediff-1.49-pkg.tar.gz" + md5sum "de66f77ac38f2df7dd4c5a94d9582f55" + size 305252 + provides (ediff-diff ediff-help ediff-hook ediff-init ediff-merg ediff-mult ediff-ptch ediff-tbar ediff-util ediff-vers ediff-wind ediff) + requires (pcl-cvs elib dired xemacs-base edebug prog-modes) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(debug + (standards-version 1.1 + version "1.17" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "GUD, gdb, dbx debugging support." + filename "debug-1.17-pkg.tar.gz" + md5sum "e45715132f64e4dbc7f14a22128b9279" + size 108073 + provides (dbx debug-toolbar gdb-highlight gdb gdbsrc gud history) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(c-support + (standards-version 1.1 + version "1.18" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Basic single-file add-ons for editing C code." + filename "c-support-1.18-pkg.tar.gz" + md5sum "950c5d610fb614bd418863075cde1c4c" + size 70705 + provides (c-comment-edit cmacexp ctypes hideif hideshow) + requires (cc-mode xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(ada + (standards-version 1.1 + version "1.14" + author-version "2.27" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Ada language support." + filename "ada-1.14-pkg.tar.gz" + md5sum "f2635d2b432f2a7cd456df760d622e3c" + size 55836 + provides (ada-mode ada-stmt) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(cc-mode + (standards-version 1.1 + version "1.41" + author-version "5.30.7" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Martin Stjernholm " + distribution xemacs + priority medium + category "standard" + dump nil + description "C, C++, Objective-C, Java, CORBA IDL, Pike and AWK language support." + filename "cc-mode-1.41-pkg.tar.gz" + md5sum "31b9f8e38d95e6b5dd079c14f88ef360" + size 513369 + provides (cc-align cc-awk cc-bytecomp cc-cmds cc-compat cc-defs cc-engine cc-fix cc-fonts cc-guess cc-langs cc-lobotomy cc-menus cc-mode cc-styles cc-vars) + requires (xemacs-base mail-lib) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(semantic + (standards-version 1.1 + version "1.18" + author-version "1.4.2" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Eric M. Ludlam " + distribution xemacs + priority low + category "standard" + dump nil + description "Semantic bovinator (Yacc/Lex for XEmacs). Includes Senator." + filename "semantic-1.18-pkg.tar.gz" + md5sum "bb333c47f371748a1e923893c98d7b3f" + size 443092 + provides (document-vars document semantic-analyze semantic-bnf semantic-c semantic-cb semantic-chart semantic-ctxt semantic-el semantic-example semantic-ia-sb semantic-ia semantic-imenu semantic-java semantic-load semantic-make semantic-sb semantic-scm semantic-skel semantic-texi semantic-util-modes semantic-util semantic semanticdb senator sformat working) + requires (eieio xemacs-base xemacs-devel edit-utils speedbar texinfo fsf-compat cc-mode edebug) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(misc-games + (standards-version 1.1 + version "1.18" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Other amusements and diversions." + filename "misc-games-1.18-pkg.tar.gz" + md5sum "c68c91ee7eb296669388645c467fdede" + size 166817 + provides (decipher gomoku hanoi life morse rot13) + requires (xemacs-base) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mine + (standards-version 1.1 + version "1.16" + author-version "1.9" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Minehunt Game." + filename "mine-1.16-pkg.tar.gz" + md5sum "3875c5eb3c58306db3c875a18ba56ff6" + size 67161 + provides (xmine) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(games + (standards-version 1.1 + version "1.15" + author-version "1.04" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Glynn Clements " + distribution xemacs + priority low + category "standard" + dump nil + description "Tetris, Sokoban, and Snake." + filename "games-1.15-pkg.tar.gz" + md5sum "e50c1cd9ae0e9d32a022f52e795119b4" + size 37242 + provides (gamegrid snake tetris sokoban) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(cookie + (standards-version 1.1 + version "1.15" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Spook and Yow (Zippy quotes)." + filename "cookie-1.15-pkg.tar.gz" + md5sum "70b4bde06580ec71df2a23aa95808bb7" + size 35035 + provides (cookie1 yow) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(bbdb + (standards-version 1.1 + version "1.24" + author-version "2.34" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Ronan Waide " + distribution xemacs + priority medium + category "standard" + dump nil + description "The Big Brother Data Base" + filename "bbdb-1.24-pkg.tar.gz" + md5sum "bb9a7c33c742e28076643be7fda317ed" + size 373736 + provides (bbdb-com bbdb-ftp bbdb-gnus bbdb-gui bbdb-hooks bbdb-merge bbdb-mhe bbdb-migrate bbdb-print bbdb-reportmail bbdb-rmail bbdb-sc bbdb-snarf bbdb-srv bbdb-vm bbdb-w3 bbdb-whois bbdb-xemacs bbdb) + requires (bbdb edit-utils gnus mh-e rmail supercite vm tm apel mail-lib xemacs-base w3 fsf-compat eterm sh-script net-utils os-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(zenirc + (standards-version 1.1 + version "1.14" + author-version "2.112" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "ZENIRC IRC Client." + filename "zenirc-1.14-pkg.tar.gz" + md5sum "9e40efa659a867dae6aac4673b474322" + size 277304 + provides (zenirc-18 zenirc-8ball zenirc-away zenirc-bork zenirc-color zenirc-command-queue zenirc-complete zenirc-ctcp-flood zenirc-dcc zenirc-doto zenirc-fill zenirc-finnish zenirc-format zenirc-fortran zenirc-french zenirc-history zenirc-ignore zenirc-iwantop zenirc-klingon zenirc-latin zenirc-meditate zenirc-netsplit zenirc-notify zenirc-oink zenirc-ojnk zenirc-pjg zenirc-popup zenirc-random-away zenirc-random-nick zenirc-signal zenirc-stamp zenirc-swedish zenirc-trigger zenirc-yow-filter zenirc-yow zenirc) + requires (zenirc) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mew + (standards-version 1.1 + version "1.18" + author-version "1.94.2" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Messaging in an Emacs World." + filename "mew-1.18-pkg.tar.gz" + md5sum "09533ddf67f0948c6b4a40b996d82fbd" + size 745829 + provides (mew-addrbook mew-attach mew-bq mew-cache mew-complete mew-decode mew-demo mew-draft mew-encode mew-env mew-ext mew-fib mew-func mew-header mew-highlight mew-lang-jp mew-mark mew-message mew-mime mew-minibuf mew-mule mew-mule0 mew-mule2 mew-mule3 mew-os2 mew-pgp mew-pick mew-refile mew-scan mew-sort mew-summary mew-syntax mew-temacs mew-unix mew-vars mew-virtual mew-win32 mew-xemacs mew) + requires (mew w3 efs mail-lib xemacs-base fsf-compat) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(tm + (standards-version 1.1 + version "1.37" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Emacs MIME support. Not needed for gnus >= 5.8.0" + filename "tm-1.37-pkg.tar.gz" + md5sum "9cd28b13243debe9a986dcbd332f1ccd" + size 334179 + provides (char-util cless gnus-art-mime gnus-charset gnus-mime gnus-sum-mime latex-math-symbol mel-b mel-g mel-q mel-u mel message-mime mime-setup mu-bbdb mu-cite range sc-setup signature texi-util tl-atype tl-list tl-misc tl-num tl-seq tl-str tm-bbdb tm-def tm-edit-mc tm-edit tm-ew-d tm-ew-e tm-file tm-ftp tm-html tm-image tm-latex tm-mail tm-mh-e tm-parse tm-partial tm-pgp tm-play tm-rmail tm-setup tm-tar tm-text tm-view tm-vm tmh-comp) + requires (gnus mh-e rmail vm mailcrypt mail-lib apel xemacs-base fsf-compat sh-script net-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(gnus + (standards-version 1.1 + version "1.73" + author-version "5.10.2" + date "2003-10-13" + build-date "2003-10-13" + maintainer "Steve Youngs " + distribution xemacs + priority medium + category "standard" + dump nil + description "The Gnus Newsreader and Mailreader." + filename "gnus-1.73-pkg.tar.gz" + md5sum "a1259caa28482a71bc4dfa1e434f9511" + size 3245188 + provides (binhex canlock compface deuglify earcon flow-fill format-spec gnus-agent gnus-art gnus-async gnus-audio gnus-bcklg gnus-cache gnus-cite gnus-cus gnus-delay gnus-demon gnus-diary gnus-dired gnus-draft gnus-dup gnus-eform gnus-ems gnus-fun gnus-gl gnus-group gnus-int gnus-kill gnus-logic gnus-mh gnus-ml gnus-mlspl gnus-move gnus-msg gnus-nocem gnus-picon gnus-range gnus-registry gnus-salt gnus-score gnus-setup gnus-sieve gnus-soup gnus-spec gnus-srvr gnus-start gnus-sum gnus-topic gnus-undo gnus-util gnus-uu gnus-vm gnus-win gnus-xmas gnus ietf-drums imap mail-parse mail-prsvr mail-source mailcap message messagexmas messcompat mm-bodies mm-decode mm-encode mm-extern mm-partial mm-url mm-util mm-uu mm-view mml-sec mml-smime mml mml1991 mml2015 nnagent nnbabyl nndb nndiary nndir nndoc nndraft nneething nnfolder nngateway nnheader nnheaderxm nnimap nnkiboze nnlistserv nnmail nnmaildir nnmbox nnmh nnml nnnil nnoo nnrss nnslashdot nnsoup nnspool nntp nnultimate nnvirtual nnwarchive nnweb nnwfm parse-time qp rfc1843 rfc2045 rfc2047 rfc2231 score-mode smiley smime spam-report spam-stat spam time-date utf7 uudecode webmail yenc gnus-idna gpg-ring gpg hashcash vcard) + requires (gnus w3 mh-e mailcrypt rmail eterm mail-lib xemacs-base fsf-compat ecrypto tm apel pgg net-utils sh-script os-utils dired sieve sasl) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(rmail + (standards-version 1.1 + version "1.14" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "An obsolete Emacs mailer." + filename "rmail-1.14-pkg.tar.gz" + md5sum "4409fc7ff5134ff562ff1357a014a41b" + size 96995 + provides (rmail-kill rmail-xemacs rmail rmailsort) + requires (tm apel mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mailcrypt + (standards-version 1.1 + version "2.13" + author-version "3.5.8" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Support for messaging encryption with PGP." + filename "mailcrypt-2.13-pkg.tar.gz" + md5sum "efe51870b559239cf48a102ea8a89e2f" + size 154111 + provides (expect mailcrypt) + requires (mail-lib fsf-compat xemacs-base cookie gnus mh-e rmail vm) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(supercite + (standards-version 1.1 + version "1.20" + author-version "3.55x3" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "An Emacs citation tool for News & Mail messages." + filename "supercite-1.20-pkg.tar.gz" + md5sum "277fb688d3765c0434e34013e811e94d" + size 100553 + provides (supercite) + requires (mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(mh-e + (standards-version 1.1 + version "1.27" + author-version "7.4.2" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Steve Youngs " + distribution xemacs + priority low + category "standard" + dump nil + description "Front end support for MH." + filename "mh-e-1.27-pkg.tar.gz" + md5sum "5b886efc6e93f97a61237dade2f360ee" + size 577724 + provides (mh-alias mh-comp mh-customize mh-e mh-funcs mh-gnus mh-identity mh-inc mh-index mh-junk mh-loaddefs mh-mime mh-pick mh-seq mh-speed mh-unit mh-utils mh-xemacs-compat mh-xemacs-icons) + requires (gnus mail-lib xemacs-base speedbar rmail tm apel sh-script fsf-compat xemacs-devel net-utils eterm os-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(gnats + (standards-version 1.1 + version "1.16" + author-version "3.101" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "XEmacs bug reports." + filename "gnats-1.16-pkg.tar.gz" + md5sum "678c190f7cd184426dcccc0f3a6d10b2" + size 188963 + provides (gnats gnats-admin send-pr) + requires (mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(footnote + (standards-version 1.1 + version "1.16" + author-version "0.18x" + date "2003-10-31" + build-date "2003-10-31" + maintainer "SL Baur " + distribution xemacs + priority low + category "standard" + dump nil + description "Footnoting in mail message editing modes." + filename "footnote-1.16-pkg.tar.gz" + md5sum "79dc557f3be890dc6f3e7793fef6f1b6" + size 22152 + provides (footnote-cyrillic footnote-greek footnote-han footnote-hebrew footnote-kana footnote) + requires (mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(eudc + (standards-version 1.1 + version "1.39" + author-version "1.32" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Oscar Figueiredo " + distribution xemacs + priority low + category "standard" + dump nil + description "Emacs Unified Directory Client (LDAP, PH)." + filename "eudc-1.39-pkg.tar.gz" + md5sum "1c725e74136dc51c02f4e7b7642140a7" + size 79488 + provides (eudc eudc-vars eudc-hotlist eudc-export eudc-bob eudcb-ldap eudcb-ph eudcb-bbdb) + requires (fsf-compat xemacs-base bbdb mail-lib gnus rmail tm apel eterm sh-script net-utils) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(net-utils + (standards-version 1.1 + version "1.33" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Miscellaneous Networking Utilities." + filename "net-utils-1.33-pkg.tar.gz" + md5sum "9470e0dc21c8dd3c1d859ce7541f31c0" + size 137514 + provides (ilisp-browse-cltl2 xemacsbug feedmail metamail net-utils rcompile shadowfile webjump webster-www dig dns xml) + requires (bbdb w3 efs mail-lib xemacs-base fsf-compat eterm sh-script gnus rmail tm apel) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(w3 + (standards-version 1.1 + version "1.29" + author-version "4.0pre47" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "A Web browser." + filename "w3-1.29-pkg.tar.gz" + md5sum "088e276b855e95b2032aa58160ffeba2" + size 694178 + provides (css devices w3-auto dsssl-flow dsssl font images mm mule-sysdp socks ssl urlauth url-cache url-cookie url-file url-gopher url-gw url-http url-ldap url-mail url-misc url-news url-ns url-parse url-vars url w3-about w3-auto w3-cfg w3-cus w3-display w3-emacs19 w3-e19 w3-e20 w3-elisp w3-emulate w3-forms w3-hot w3-hotindex w3-imap w3-java w3-jscript w3-keyword w3-latex w3-menu w3-mouse w3-parse w3-print w3-props w3-script w3-structure w3-speak w3-style w3-sysdp w3-toolbar w3-vars w3-widget w3-xemacs w3-xemac w3) + requires (w3 mail-lib xemacs-base ecrypto) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(vm + (standards-version 1.1 + version "7.18" + author-version "7.17" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Kyle Jones " + distribution xemacs + priority medium + category "standard" + dump nil + description "An Emacs mailer." + filename "vm-7.18-pkg.tar.gz" + md5sum "25a353d78f64c2dd2e1001719158a315" + size 812340 + provides (tapestry vm-byteopts vm-delete vm-digest vm-easymenu vm-edit vm-folder vm-imap vm-license vm-macro vm-mark vm-menu vm-message vm-mime vm-minibuf vm-misc vm-motion vm-mouse vm-page vm-pop vm-reply vm-save vm-search vm-sort vm-startup vm-summary vm-thread vm-toolbar vm-undo vm-user vm-vars vm vm-version vm-virtual vm-window) + requires (mail-lib xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sounds-wav + (standards-version 1.1 + version "1.12" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "XEmacs Microsoft sound files." + filename "sounds-wav-1.12-pkg.tar.gz" + md5sum "3045a90ca53b22ebb7aa52f611bafcd3" + size 149624 + provides () + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(sounds-au + (standards-version 1.1 + version "1.12" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "XEmacs Sun sound files." + filename "sounds-au-1.12-pkg.tar.gz" + md5sum "9bf0b5a2ac38a4fe2d710063ddcaadd3" + size 126817 + provides () + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(xemacs-devel + (standards-version 1.1 + version "1.60" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority medium + category "standard" + dump nil + description "Emacs Lisp developer support." + filename "xemacs-devel-1.60-pkg.tar.gz" + md5sum "db789317a15bf3a73bacd7b337ec7a34" + size 232116 + provides (checkdoc docref eldoc elp eval-expr find-func hide-copyleft ielm patcher pp trace patch-keywords) + requires (xemacs-base ispell mail-lib gnus rmail tm apel sh-script net-utils eterm) + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(tooltalk + (standards-version 1.1 + version "1.15" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Support for building with Tooltalk." + filename "tooltalk-1.15-pkg.tar.gz" + md5sum "3d1a4ddbd0da23033a6dc8a8c90849e2" + size 9749 + provides () + requires () + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(elib + (standards-version 1.1 + version "1.11" + author-version "1.0" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "Portable Emacs Lisp utilities library." + filename "elib-1.11-pkg.tar.gz" + md5sum "914b735704c60f7d534398025ae725db" + size 73387 + provides (avltree bintree cookie dll elib-node queue-f queue-m read stack-f stack-m string) + requires () + type single +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(edebug + (standards-version 1.1 + version "1.20" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "An Emacs Lisp debugger." + filename "edebug-1.20-pkg.tar.gz" + md5sum "ff397fa7dba09ab0a52a83649b8a14d8" + size 115244 + provides (edebug cl-read cust-print eval-reg cl-specs) + requires (xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(Sun + (standards-version 1.1 + version "1.15" + author-version "No-Upstream-Ver" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority low + category "standard" + dump nil + description "Support for Sparcworks." + filename "Sun-1.15-pkg.tar.gz" + md5sum "ac4b09817681596ba032cf868c7c6dac" + size 64660 + provides (sccs eos-browser eos-common eos-debugger eos-debugger eos-editor eos-init eos-load eos-menubar eos-toolbar sunpro) + requires (cc-mode xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(apel + (standards-version 1.1 + version "1.27" + author-version "10.2" + date "2003-10-31" + build-date "2003-10-31" + maintainer "XEmacs Development Team " + distribution xemacs + priority high + category "standard" + dump nil + description "A Portable Emacs Library. Used by XEmacs MIME support." + filename "apel-1.27-pkg.tar.gz" + md5sum "2f35080836afe0730b2fe664f90b01be" + size 108585 + provides (atype emu-20 emu-e19 emu-x20 emu-xemacs emu file-detect filename install mule-caesar path-util richtext std11-parse std11 tinyrich) + requires (fsf-compat xemacs-base) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(efs + (standards-version 1.0 + version "1.32" + author-version "1.22" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Mike Sperber " + distribution stable + priority medium + category "standard" + dump nil + description "Treat files on remote systems the same as local files." + filename "efs-1.32-pkg.tar.gz" + md5sum "6123c11bc7a9c993429e9976f7bf42c4" + size 375800 + provides (efs) + requires (xemacs-base dired) + type regular +)) +)) +;;;@@@ +(package-get-update-base-entry (quote +(dired + (standards-version 1.0 + version "1.15" + author-version "7.11" + date "2003-10-31" + build-date "2003-10-31" + maintainer "Mike Sperber " + distribution stable + priority medium + category "standard" + dump nil + description "Manage file systems." + filename "dired-1.15-pkg.tar.gz" + md5sum "3bd864d76ba88c2a8a42772222a2743f" + size 198282 + provides (diff dired) + requires (xemacs-base prog-modes) + type regular +)) +)) +;;;@@@ +;; Package Index file ends here +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.2.3 (FreeBSD) +Comment: The XEmacs Development Team + +iD4DBQE/s2HKgu3ywdHdhM0RAsIRAJiVkwgHSIPBMZBJlZdA06kOtKV2AKCqhmSb +/TUbeZRrIemjq9es9VqYJg== +=n9fY +-----END PGP SIGNATURE----- diff -u -r -N xemacs-21.4.14/etc/package-index.LATEST.pgp xemacs-21.4.15/etc/package-index.LATEST.pgp --- xemacs-21.4.14/etc/package-index.LATEST.pgp 2003-07-31 00:40:35.000000000 -0400 +++ xemacs-21.4.15/etc/package-index.LATEST.pgp 1969-12-31 19:00:00.000000000 -0500 @@ -1,2512 +0,0 @@ -;; Package Index file -- Do not edit manually. -;;;@@@ -(package-get-update-base-entry (quote -(ecb - (standards-version 1.1 - version "1.08" - author-version "1.94" - date "2003-06-27" - build-date "2003-06-27" - maintainer "Klaus Berndl " - distribution xemacs - priority low - category "standard" - dump nil - description "Emacs source code browser." - filename "ecb-1.08-pkg.tar.gz" - md5sum "840dabab1055bd61a3c2ecd5d1b5a7a0" - size 463303 - provides (ecb-buffertab ecb-compilation ecb-create-layout ecb-cycle ecb ecb-eshell ecb-examples ecb-face ecb-help ecb-layout ecb-layout-defs ecb-mode-line ecb-navigate ecb-speedbar ecb-tod ecb-autogen ecb-jde ecb-upgrade ecb-util silentcomp tree-buffer) - requires (xemacs-base semantic eieio fsf-compat edit-utils jde mail-lib eshell ediff xemacs-devel speedbar) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(pgg - (standards-version 1.1 - version "1.03" - author-version "0.1" - date "2003-05-14" - build-date "2003-05-14" - maintainer "Simon Josefsson " - distribution xemacs - priority low - category "standard" - dump nil - description "Emacs interface to various PGP implementations." - filename "pgg-1.03-pkg.tar.gz" - md5sum "d5f112441b77a17e23fabd6bf4f17f49" - size 31526 - provides (pgg pgg-def pgg-parse pgg-gpg pgg-pgp pgg-pgp5) - requires (xemacs-base fsf-compat edebug) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(perl-modes - (standards-version 1.1 - version "1.04" - author-version "21.4" - date "2003-01-18" - build-date "2003-01-18" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Perl support." - filename "perl-modes-1.04-pkg.tar.gz" - md5sum "13cd4e312af571aefbf5415cfefc4fad" - size 161021 - provides (cperl-mode perl-mode) - requires (xemacs-base ispell ps-print edit-utils fsf-compat) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(python-modes - (standards-version 1.1 - version "1.02" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Python support." - filename "python-modes-1.02-pkg.tar.gz" - md5sum "738bbb00e9bd21d3091ae41aedaac2f9" - size 81943 - provides (pydoc python-mode) - requires (xemacs-base mail-lib) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ruby-modes - (standards-version 1.1 - version "1.01" - author-version "1.6.8" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Ruby support." - filename "ruby-modes-1.01-pkg.tar.gz" - md5sum "923181c6dd43210e7c85c971c754f38a" - size 21775 - provides (inf-ruby ruby-mode rubydb) - requires (xemacs-base debug) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(fortran-modes - (standards-version 1.1 - version "1.02" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Fortran support." - filename "fortran-modes-1.02-pkg.tar.gz" - md5sum "ae3d346c19382f07227dd8756da53134" - size 66600 - provides (f90 fortran) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(psgml-dtds - (standards-version 1.1 - version "1.02" - author-version "21.4" - date "2002-08-29" - build-date "2002-08-29" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Deprecated collection of DTDs for psgml." - filename "psgml-dtds-1.02-pkg.tar.gz" - md5sum "90100411b64045dae38166116d1f8e3f" - size 367102 - provides () - requires (xemacs-base psgml edit-utils mail-lib fsf-compat eterm sh-script) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(docbookide - (standards-version 1.1 - version "0.06" - author-version "0.1" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "DocBook editing support." - filename "docbookide-0.06-pkg.tar.gz" - md5sum "625c9ef5bb10c655b6f6dcba1b42ba2a" - size 31968 - provides (dbide-abbrev dbide-data dbide-font dbide-process docbookide) - requires (xemacs-base ispell mail-lib) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ecrypto - (standards-version 1.1 - version "0.13" - author-version "2.0" - date "2003-06-22" - build-date "2003-06-22" - maintainer "Simon Josefsson " - distribution xemacs - priority low - category "standard" - dump nil - description "Crypto functionality in Emacs Lisp." - filename "ecrypto-0.13-pkg.tar.gz" - md5sum "b05bf91a006f1778c6199ce263548e7e" - size 68668 - provides (ascii-armor blowfish des hex-util md4 md5-dl md5-el md5 paranoid rander rc16 rijndael sha1-dl sha1-el sha1) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ocaml - (standards-version 1.1 - version "0.04" - author-version "3.06" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Objective Caml editing support." - filename "ocaml-0.04-pkg.tar.gz" - md5sum "3b2bc2c431e334050074aebcf260d06e" - size 64814 - provides (caml-compat camldebug caml caml-font caml-help inf-caml) - requires (xemacs-base fsf-compat) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sasl - (standards-version 1.1 - version "1.13" - author-version "1.14.4" - date "2003-05-28" - build-date "2003-05-28" - maintainer "Simon Josefsson " - distribution xemacs - priority low - category "standard" - dump nil - description "Simple Authentication and Security Layer (SASL) library." - filename "sasl-1.13-pkg.tar.gz" - md5sum "d6121fb31ab47213f97862dc0d0ec7a1" - size 27008 - provides (hmac-def hmac-md5 hmac-sha1 ntlm sasl sasl-cram sasl-digest sasl-ntlm sasl-plain sasl-login sasl-anonymous) - requires (ecrypto) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sml-mode - (standards-version 1.1 - version "0.09" - author-version "3.9.5" - date "2003-01-18" - build-date "2003-01-18" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "SML editing support." - filename "sml-mode-0.09-pkg.tar.gz" - md5sum "2022d71197f600716f0b41da3794c19b" - size 81547 - provides (sml-compat sml-defs sml-mode sml-move sml-proc sml-util) - requires (xemacs-base edebug fsf-compat) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ess - (standards-version 1.1 - version "1.04" - author-version "5.1.21" - date "2003-06-11" - build-date "2003-06-11" - maintainer "A.J. Rossini " - distribution xemacs - priority medium - category "standard" - dump nil - description "ESS: Emacs Speaks Statistics." - filename "ess-1.04-pkg.tar.gz" - md5sum "ea46dcb7f35e56d9426c1749ee6c3fb5" - size 446476 - provides (ess-batch ess-comp ess-cust ess-dump ess-emcs ess-font-lock ess-help ess-inf ess-iw32 ess-latex-mode ess-menu ess-mode ess-mous ess-noweb ess-site ess-sysdp ess-utils ess-vars ess essa-r essa-sas essd-arc essd-els essd-r essd-omg essd-r essd-s3 essd-s4 essd-sas essd-sp3 essd-sp4 essd-sp5 essd-sp6 essd-sta essd-vst essd-xls essddr essdsp6w essl-bug essl-lsp essl-omg essl-py essl-s essl-sas essl-sta make-regexp mouseme msdos noweb-font-lock-mode noweb-mode) - requires (xemacs-base mail-lib fsf-compat edit-utils speedbar sh-script eterm) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(haskell-mode - (standards-version 1.1 - version "1.05" - author-version "1.44" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Haskell editing support." - filename "haskell-mode-1.05-pkg.tar.gz" - md5sum "198a9d68d1b4115c9faf45e14c264f54" - size 94162 - provides (haskell-decl-scan haskell-doc haskell-font-lock haskell-indent haskell-mode haskell-simple-indent) - requires (dired mail-lib xemacs-base edit-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(xslide - (standards-version 1.1 - version "1.07" - author-version "0.2.1" - date "2003-06-28" - build-date "2003-06-28" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "XSL editing support." - filename "xslide-1.07-pkg.tar.gz" - md5sum "1e07a704f0aba2774feb20ee36065c36" - size 37872 - provides (xslide-abbrev xslide-data xslide-font xslide-process xslide) - requires (ispell mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(liece - (standards-version 1.1 - version "1.12" - author-version "1.4.9" - date "2003-04-22" - build-date "2003-04-22" - maintainer "Daiki Ueno " - distribution xemacs - priority high - category "standard" - dump nil - description "IRC (Internet Relay Chat) client for Emacs." - filename "liece-1.12-pkg.tar.gz" - md5sum "c7f2aab45f8ada9398d4b0807e80433a" - size 199275 - provides (liece-xemacs gettext liece-clfns liece-handler liece-compat liece-version liece-vars liece-globals liece-inlines liece-filter liece-coding liece-dcc liece-menu liece-000 liece-200 liece-300 liece-400 liece-500 liece-nick liece-channel liece-commands liece-ctcp liece-q-el liece-message liece-handle liece-hilit liece-intl liece-mail liece-minibuf liece-misc liece-tcp liece-url liece-x-face liece-window liece) - requires (apel mail-lib fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(latin-unity - (standards-version 1.1 - version "1.07" - author-version "1.07" - date "2002-11-01" - build-date "2002-11-01" - maintainer "Stephen J. Turnbull " - distribution mule - priority high - category "mule" - dump nil - description "MULE: find single ISO 8859 character set to encode a buffer." - filename "latin-unity-1.07-pkg.tar.gz" - md5sum "7d4f163e1d98af367fab9f4ea5d01d8d" - size 116377 - provides (latin-unity latin-unity-tables latin-unity-utils) - requires (mule-base mule-ucs leim fsf-compat dired) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mmm-mode - (standards-version 1.1 - version "1.00" - author-version "0.4.7" - date "2002-02-24" - build-date "2002-02-28" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Multiple major modes in a single buffer" - filename "mmm-mode-1.00-pkg.tar.gz" - md5sum "c07c752ffd029d9a430c2fb118127e88" - size 176080 - provides (mmm-auto mmm-class mmm-cmds mmm-compat mmm-mason mmm-mode mmm-region mmm-rpm mmm-sample mmm-univ mmm-utils mmm-vars) - requires (xemacs-base fsf-compat ) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ibuffer - (standards-version 1.1 - version "1.08" - author-version "21.5b6" - date "2002-07-14" - build-date "2002-07-14" - maintainer "John Paul Wallington " - distribution xemacs - priority medium - category "standard" - dump nil - description "Advanced replacement for buffer-menu" - filename "ibuffer-1.08-pkg.tar.gz" - md5sum "e7203eeeca98a89c2bfe051d81c729de" - size 87113 - provides (ibuf-ext ibuf-macs ibuffer) - requires (ibuffer xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(xemacs-base - (standards-version 1.1 - version "1.78" - author-version "21.4" - date "2003-06-11" - build-date "2003-06-11" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "Fundamental XEmacs support, you almost certainly need this." - filename "xemacs-base-1.78-pkg.tar.gz" - md5sum "2f49dd65c93ced29f2a9d97bf3c4c9b3" - size 469861 - provides (add-log advice-preload advice annotations assoc case-table chistory comint-xemacs comint compile debug ebuff-menu echistory edmacro ehelp electric enriched env facemenu ffap helper imenu iso-syntax macros novice outline passwd pp regexp-opt regi ring shell skeleton sort thing time-stamp timezone tq xbm-button xpm-button) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(tramp - (standards-version 1.1 - version "1.15" - author-version "2.0.35" - date "2003-06-20" - build-date "2003-06-20" - maintainer "Kai Großjohann " - distribution xemacs - priority low - category "standard" - dump nil - description "Remote shell-based file editing." - filename "tramp-1.15-pkg.tar.gz" - md5sum "239ea97dafee64640e7c10082dd131d9" - size 247697 - provides (tramp tramp-efs tramp-ftp tramp-smb tramp-util tramp-uu - tramp-vc trampcache) - requires (tramp xemacs-base vc fsf-compat efs dired mail-lib gnus ediff) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(text-modes - (standards-version 1.1 - version "1.61" - author-version "21.4" - date "2003-06-08" - build-date "2003-06-08" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "Miscellaneous support for editing text files." - filename "text-modes-1.61-pkg.tar.gz" - md5sum "d558a6d3137209ac2dac8dfb9259129a" - size 359003 - provides (ansi-color autoinsert crontab-edit filladapt flyspell folding fold-isearch hexl htmlize image-mode iso-acc iso-ascii iso-cvt iso-insert iso-swed rtf-support swedish tabify whitespace-mode winmgr-mode xpm-mode xrdb-mode apache-mode po-mode po-compat css-mode) - requires (ispell fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(pcl-cvs - (standards-version 1.1 - version "1.64" - author-version "R-2_9_9" - date "2002-07-30" - build-date "2002-07-30" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "CVS frontend." - filename "pcl-cvs-1.64-pkg.tar.gz" - md5sum "3d8f9aac5c5edefec62a33cb9695db9f" - size 161512 - provides (cvs-compat cvs-edit cvs-log cvs-status easy-mmode pcl-cvs-defs pcl-cvs-info pcl-cvs-parse pcl-cvs-util pcl-cvs) - requires (xemacs-base elib vc dired edebug ediff edit-utils mail-lib prog-modes) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mail-lib - (standards-version 1.1 - version "1.59" - author-version "21.5b13" - date "2003-05-14" - build-date "2003-05-14" - maintainer "Simon Josefsson " - distribution xemacs - priority medium - category "standard" - dump nil - description "Fundamental lisp files for providing email support." - filename "mail-lib-1.59-pkg.tar.gz" - md5sum "576bfafe24b1b08cfdf184fe021066c9" - size 198415 - provides (base64 browse-url-xemacs browse-url highlight-headers mail-abbrevs mail-extr mail-utils mailheader netrc pop3 reporter rfc2104 rfc822 rmail rmail-mini rmailout sendmail smtpmail starttls tls) - requires (eterm xemacs-base fsf-compat sh-script ecrypto) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(jde - (standards-version 1.1 - version "1.45" - author-version "2.3.2" - date "2003-01-26" - build-date "2003-01-26" - maintainer "Andy Piper " - distribution xemacs - priority medium - category "standard" - dump nil - description "Integrated Development Environment for Java." - filename "jde-1.45-pkg.tar.gz" - md5sum "64c39644d4e12e053aa0eb982d473405" - size 2403338 - provides (beanshell efc jde-ant jde-bug jde-checkstyle jde-compat jde-compile jde-complete jde-db jde-dbo jde-dbs jde-ejb jde-gen jde-help jde-imenu jde-import jde-java-font-lock jde-java-grammar jde-javadoc-gen jde-javadoc jde-jdb jde-make jde-open-source jde-package jde-parse-class jde-parse jde-run jde-setnu jde-stat jde-util jde-which-method jde-widgets jde-wiz jde-xref jde tree-widget) - requires (jde cc-mode semantic debug speedbar edit-utils eterm mail-lib xemacs-base xemacs-devel eieio elib sh-script fsf-compat) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(fsf-compat - (standards-version 1.1 - version "1.12" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "FSF Emacs compatibility files." - filename "fsf-compat-1.12-pkg.tar.gz" - md5sum "43183434592aed9a96e38ab48585b5fd" - size 21442 - provides (overlay thingatpt timer x-popup-menu goto-addr) - requires (xemacs-base) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(edit-utils - (standards-version 1.1 - version "2.02" - author-version "21.4" - date "2003-06-20" - build-date "2003-06-20" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "Miscellaneous editor extensions, you probably need this." - filename "edit-utils-2.02-pkg.tar.gz" - md5sum "9155b838e5c09dd07dcefc926f5433e4" - size 720244 - provides (abbrevlist after-save-commands atomic-extents avoid backup-dir balloon-help big-menubar blink-cursor blink-paren bookmark compare-w completion dabbrev desktop detached-minibuf edit-toolbar fast-lock file-part floating-toolbar flow-ctrl foldout func-menu hippie-exp icomplete id-select info-look iswitchb lazy-lock lazy-shot live-icon makesum man mic-paren paren mode-motion+ outl-mouse outln-18 page-ext blink-paren paren permanent-buffers popper power-macros recent-files redo reportmail resume rsz-minibuf saveconf savehist saveplace scroll-in-place setnu shell-font tempo toolbar-utils tree-menu uniquify vertical-mode where-was-i-db winring) - requires (xemacs-base xemacs-devel fsf-compat dired mail-lib) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(skk - (standards-version 1.1 - version "1.23" - author-version "10.62a" - date "2002-09-25" - build-date "2002-09-25" - maintainer "XEmacs Development Team " - distribution mule - priority medium - category "mule" - dump nil - description "MULE: Japanese Language Input Method." - filename "skk-1.23-pkg.tar.gz" - md5sum "dc35f20896a56c8cf2e7ba16b15e453b" - size 1506691 - provides (skk-auto skk-comp skk-cursor skk-develop skk-foreword skk-gadget skk-isearch skk-kakasi skk-kcode skk-leim skk-look skk-num skk-obsolete skk-server skk-tut skk-vars skk-viper skk vip) - requires (viper mule-base elib xemacs-base apel) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ps-print - (standards-version 1.1 - version "1.08" - author-version "6.5.6" - date "2002-08-29" - build-date "2002-08-29" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Printing functions and utilities" - filename "ps-print-1.08-pkg.tar.gz" - md5sum "bbfb58fe514cf4bd6fbec2f62c43c823" - size 153729 - provides (lpr ps-bdf ps-mule ps-print) - requires (text-modes) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sieve - (standards-version 1.1 - version "1.13" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Simon Josefsson " - distribution xemacs - priority low - category "standard" - dump nil - description "Manage Sieve email filtering scripts." - filename "sieve-1.13-pkg.tar.gz" - md5sum "a8816344f83e92821989f9298c415038" - size 25479 - provides (sieve sieve-mode sieve-manage) - requires (xemacs-base mail-lib cc-mode sasl) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mule-ucs - (standards-version 1.1 - version "1.04" - author-version "0.84" - date "2002-03-25" - build-date "2002-03-25" - maintainer "Stephen J. Turnbull " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Extended coding systems (including Unicode) for XEmacs." - filename "mule-ucs-1.04-pkg.tar.gz" - md5sum "08df8359e7999c60f62f6ec92cccc197" - size 1313726 - provides (mccl-font mucs-ccl mucs-error mucs-type mucs mule-uni tae tbl-mg trans-util txt-tbl un-data un-define un-supple un-tools un-trbase unicode unidata utf u-cns-1 u-cns-2 u-cns-3 u-cns-4 u-cns-5 u-cns-6 u-cns-7 uascii ubig5 uetiopic ugb2312 uipa uiscii uiso8859-1 uiso8859-14 uiso8859-15 uiso8859-2 uiso8859-3 uiso8859-4 uiso8859-5 uiso8859-6 uiso8859-7 uiso8859-8 uiso8859-9 ujisx0201 ujisx0208 ujisx0212 uksc5601 usisheng usupple utibetan utis620 uviscii) - requires (mule-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(clearcase - (standards-version 1.0 - version "1.06" - author-version "21.5b6" - date "2002-06-27" - build-date "2002-06-27" - maintainer "Michael Diers " - distribution xemacs - priority low - category "standard" - dump nil - description "New Clearcase Version Control for XEmacs (UNIX, Windows)." - filename "clearcase-1.06-pkg.tar.gz" - md5sum "8f9a2485be7371b78b01b68039d91e09" - size 89634 - provides (clearcase) - requires (dired fsf-compat mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(dictionary - (standards-version 1.1 - version "1.12" - author-version "1.8" - date "2003-06-22" - build-date "2003-06-22" - maintainer "Torsten Hilbrich " - distribution xemacs - priority low - category "standard" - dump nil - description "Interface to RFC2229 dictionary servers." - filename "dictionary-1.12-pkg.tar.gz" - md5sum "717517bbad4e241f18941fd6c289b868" - size 39658 - provides (dictionary connection link) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(build - (standards-version 1.0 - version "1.10" - author-version "2.02" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Adrian Aichner " - distribution stable - priority low - category "standard" - dump nil - description "Build XEmacs from within (UNIX, Windows)." - filename "build-1.10-pkg.tar.gz" - md5sum "442bf6d4729f40545d1ee1ad8eca5a93" - size 49207 - provides (build) - requires (xemacs-base pcl-cvs dired w3 prog-modes) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(xslt-process - (standards-version 1.0 - version "1.11" - author-version "1.2.1" - date "2002-10-08" - build-date "2002-10-08" - maintainer "Ovidiu Predescu " - distribution xemacs - priority medium - category "standard" - dump nil - description "XSLT processing support." - filename "xslt-process-1.11-pkg.tar.gz" - md5sum "30273cbe2e90ae703ea410879412e68b" - size 199873 - provides (xslt-process) - requires (jde cc-mode semantic debug speedbar edit-utils eterm mail-lib xemacs-base elib eieio sh-script fsf-compat xemacs-devel) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(eieio - (standards-version 1.1 - version "1.04" - author-version "0.17" - date "2002-12-06" - build-date "2002-12-06" - maintainer "Eric Ludlam " - distribution xemacs - priority low - category "standard" - dump nil - description "Enhanced Implementation of Emacs Interpreted Objects" - filename "eieio-1.04-pkg.tar.gz" - md5sum "6504c1a9225576fd0140cba9962e191b" - size 165595 - provides (call-tree chart compare-strings eieio-base eieio-comp eieio-custom eieio-doc eieio-opt eieio-speedbar eieio-tests eieio linemark tree) - requires (speedbar xemacs-base edebug) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(egg-its - (standards-version 1.1 - version "1.26" - author-version "21.5b1" - date "2001-05-07" - build-date "2001-05-10" - maintainer "XEmacs Development Team " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Wnn (4.2 and 6) support. SJ3 support." - filename "egg-its-1.26-pkg.tar.gz" - md5sum "a69b09fedc9aee8422ed7ed35b6649eb" - size 260749 - provides (egg-cnpinyin egg-cnzhuyin egg-cwnn-leim egg-jisx0201 egg-jsymbol egg-kwnn-leim egg-leim egg-sj3-client egg-sj3-leim egg-sj3 egg-wnn egg) - requires (leim mule-base fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(edict - (standards-version 1.1 - version "1.13" - author-version "0.9.9" - date "2002-01-30" - build-date "2002-02-13" - maintainer "Stephen J. Turnbull " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Lisp Interface to EDICT, Kanji Dictionary" - filename "edict-1.13-pkg.tar.gz" - md5sum "ceef82c336de553e504aa3d216fbd366" - size 95541 - provides (dui-registry dui edict-edit edict-english edict-japanese edict-morphology edict-test edict ts-mode) - requires (mule-base xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(lookup - (standards-version 1.1 - version "1.13" - author-version "1.0" - date "2002-09-25" - build-date "2002-09-25" - maintainer "XEmacs Development Team " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Dictionary support" - filename "lookup-1.13-pkg.tar.gz" - md5sum "cd658e3024349bf67743f6a0cce96be5" - size 214806 - provides (evi-mule evi lookup-content lookup-defs lookup-entry lookup-select lookup-package lookup-select lookup-types lookup-utils lookup-vars lookup-vse lookup ndcookie ndeb ndic ndict ndkks ndmisc ndnmz ndspell ndsrd ndtp sdicf stem) - requires (mule-base cookie lookup) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(leim - (standards-version 1.1 - version "1.20" - author-version "21.4" - date "2003-01-03" - build-date "2003-01-03" - maintainer "XEmacs Development Team " - distribution mule - priority medium - category "mule" - dump nil - description "MULE: Quail. All non-English and non-Japanese language support." - filename "leim-1.20-pkg.tar.gz" - md5sum "33e2983108fb7c55f748b855a40e2a04" - size 1708682 - provides () - requires (leim mule-base fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(locale - (standards-version 1.1 - version "1.20" - author-version "21.4" - date "2002-11-01" - build-date "2002-11-01" - maintainer "XEmacs Development Team " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Localized menubars and localized splash screens." - filename "locale-1.20-pkg.tar.gz" - md5sum "f91249a741613f91f89369eb26458a2d" - size 36563 - provides () - requires (mule-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mule-base - (standards-version 1.1 - version "1.43" - author-version "21.5b13" - date "2003-05-11" - build-date "2003-05-11" - maintainer "XEmacs Development Team " - distribution mule - priority high - category "mule" - dump nil - description "MULE: Basic Mule support, required for building with Mule." - filename "mule-base-1.43-pkg.tar.gz" - md5sum "5caadede1749519085b30a016c99a7af" - size 444550 - provides (canna-leim canna char-table china-util cyril-util isearch-ext japan-util ccl can-n-egg mule-help) - requires (fsf-compat xemacs-base apel) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(strokes - (standards-version 1.1 - version "1.08" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "oa" - dump nil - description "Mouse enhancement utility." - filename "strokes-1.08-pkg.tar.gz" - md5sum "c5ab0860ceb23b40798b11a1fa4c0240" - size 43486 - provides (strokes) - requires (text-modes edit-utils mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(time - (standards-version 1.1 - version "1.13" - author-version "1.17" - date "2003-05-11" - build-date "2003-05-11" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Display time & date on the modeline." - filename "time-1.13-pkg.tar.gz" - md5sum "6fff6a2cf70c65710a905de3bbbc2e5d" - size 20550 - provides (time) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(slider - (standards-version 1.1 - version "1.13" - author-version "0.3x1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "oa" - dump nil - description "User interface tool." - filename "slider-1.13-pkg.tar.gz" - md5sum "3fbc16b2caeef30e87969e19efa40f32" - size 12021 - provides (slider color-selector) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sgml - (standards-version 1.1 - version "1.08" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "oa" - dump nil - description "SGML/Linuxdoc-SGML editing." - filename "sgml-1.08-pkg.tar.gz" - md5sum "bdadf462489fa1540cc56d1c561aaa54" - size 26964 - provides (sgml linuxdoc-sgml) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(psgml - (standards-version 1.1 - version "1.40" - author-version "1.3.1" - date "2003-01-19" - build-date "2003-01-19" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Validated HTML/SGML editing." - filename "psgml-1.40-pkg.tar.gz" - md5sum "794e98e745f17aaa5fc3d731a59b9d0d" - size 301036 - provides (iso-sgml psgml-api psgml-charent psgml-debug psgml-dtd psgml-edit psgml-fs psgml-html psgml-info psgml-parse psgml-sysdep psgml-xemacs psgml sgml-mode) - requires (xemacs-base edit-utils edebug xemacs-devel mail-lib fsf-compat eterm sh-script ps-print) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(pc - (standards-version 1.1 - version "1.25" - author-version "21.5b6" - date "2002-06-04" - build-date "2002-06-04" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "PC style interface emulation." - filename "pc-1.25-pkg.tar.gz" - md5sum "03b7fcc55e1ce79a6017cdfa7fd49f3d" - size 17429 - provides (delbs fusion pc-select pending-del s-region) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ispell - (standards-version 1.1 - version "1.24" - author-version "3.2" - date "2002-01-07" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Spell-checking with GNU ispell." - filename "ispell-1.24-pkg.tar.gz" - md5sum "409bfa4ca95d91bc03d8dcfe7c8f7810" - size 72543 - provides (ispell) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(hm--html-menus - (standards-version 1.1 - version "1.21" - author-version "5.9" - date "2003-06-28" - build-date "2003-06-28" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "HTML editing." - filename "hm--html-menus-1.21-pkg.tar.gz" - md5sum "77d84c92c6ce3109dbec828ac24bb25d" - size 179706 - provides (adapt hm--date hm--html-configuration hm--html-drag-and-drop hm--html-indentation hm--html-keys hm--html-menu hm--html-mode hm--html-not-standard hm--html html-view internal-drag-and-drop tmpl-minor-mode) - requires (dired xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(frame-icon - (standards-version 1.1 - version "1.09" - author-version "21.1" - date "1998-07-14" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "oa" - dump nil - description "Set up mode-specific icons for each frame under XEmacs" - filename "frame-icon-1.09-pkg.tar.gz" - md5sum "91922e43447422f175065428367fb00b" - size 33436 - provides (forms forms-mode) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(forms - (standards-version 1.1 - version "1.14" - author-version "2.37" - date "2002-01-07" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Forms editing support (obsolete, use Widget instead)." - filename "forms-1.14-pkg.tar.gz" - md5sum "c6530292a349a0c567311502c2038270" - size 48263 - provides (forms forms-mode) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(calendar - (standards-version 1.1 - version "1.19" - author-version "21.4" - date "2002-09-26" - build-date "2002-09-26" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Calendar and diary support." - filename "calendar-1.19-pkg.tar.gz" - md5sum "f41fe8405fc58fefe03fef27428223fe" - size 252793 - provides (appt cal-china cal-coptic cal-dst cal-french cal-hebrew cal-islam cal-iso cal-japanese cal-julian cal-mayan cal-move cal-persia cal-tex cal-x cal-xemacs calendar diary-lib holidays lunar solar) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(calc - (standards-version 1.1 - version "1.23" - author-version "2.02fX3" - date "2002-05-09" - build-date "2002-05-10" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Emacs calculator" - filename "calc-1.23-pkg.tar.gz" - md5sum "e66651dacc67325f6e6d033f80f2e989" - size 1615158 - provides (calc-ext calc-macs calc) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(speedbar - (standards-version 1.1 - version "1.26" - author-version "0.14beta4" - date "2003-01-03" - build-date "2003-01-03" - maintainer "Eric M. Ludlam " - distribution xemacs - priority low - category "standard" - dump nil - description "Provides a separate frame with convenient references." - filename "speedbar-1.26-pkg.tar.gz" - md5sum "1bcc0c31772870347b33fed82da4dc91" - size 163116 - provides (bigclock dframe rpm sb-ant sb-gud sb-html sb-image sb-info sb-rmail sb-texinfo sb-w3 speedbar) - requires (xemacs-base edebug) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(pcomplete - (standards-version 1.1 - version "1.02" - author-version "1.1.6" - date "2002-10-14" - build-date "2002-10-14" - maintainer "John Wiegley " - distribution xemacs - priority medium - category "standard" - dump nil - description "Provides programmatic completion." - filename "pcomplete-1.02-pkg.tar.gz" - md5sum "badc7fe7baa939025c954e37168a8157" - size 37301 - provides (pcomplete) - requires (sh-script xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(eshell - (standards-version 1.1 - version "1.05" - author-version "2.4.1" - date "2002-12-06" - build-date "2002-12-06" - maintainer "John Wiegley " - distribution xemacs - priority medium - category "standard" - dump nil - description "Command shell implemented entirely in Emacs Lisp" - filename "eshell-1.05-pkg.tar.gz" - md5sum "657a26052b757a3caeb3a8f5256bfa64" - size 231854 - provides (em-alias em-banner em-basic em-cmpl em-dirs em-glob em-hist em-ls em-pred em-prompt em-rebind em-script em-smart em-term em-unix em-xtra esh-arg esh-cmd esh-ext esh-io esh-maint esh-mode esh-module esh-opt esh-proc esh-test esh-toggle esh-util esh-var eshell) - requires (xemacs-base eterm) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(view-process - (standards-version 1.1 - version "1.12" - author-version "2.4" - date "2002-08-26" - build-date "2002-08-26" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "A Unix process browsing tool." - filename "view-process-1.12-pkg.tar.gz" - md5sum "5259a3dbaa145eba1795d9b481589833" - size 60436 - provides (view-process-mode) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(os-utils - (standards-version 1.1 - version "1.31" - author-version "21.4" - date "2003-06-01" - build-date "2003-06-01" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Miscellaneous O/S utilities." - filename "os-utils-1.31-pkg.tar.gz" - md5sum "ea1a8bcaa8dde3ab5e617197d7f6d587" - size 201059 - provides (archive-mode background crypt++ crypt ftelnet inf-lisp jka-compr mchat rlogin ssh tar-mode telnet terminal uncompress) - requires (xemacs-base) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ilisp - (standards-version 1.1 - version "1.32" - author-version "5.12.0" - date "2003-05-02" - build-date "2003-05-02" - maintainer "ilisp Maintainers " - distribution xemacs - priority low - category "standard" - dump nil - description "Front-end for Inferior Lisp." - filename "ilisp-1.32-pkg.tar.gz" - md5sum "b862aeb9131e1c51272b3fddfc79f323" - size 345070 - provides (bridge comint-ipc completer ilcompat compat-fsf18 compat-fsf-19 compat-fsf-20 ilisp-chs ilisp-cl-easy-menu ilisp-ext ilisp-lw ilisp-key ilisp-menu ilisp-mnb ilisp-scheme-easy-menu ilisp il-luc19 il-luc19) - requires (xemacs-base mail-lib fsf-compat eterm sh-script) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(igrep - (standards-version 1.1 - version "1.10" - author-version "2.95" - date "2002-10-29" - build-date "2002-10-29" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Enhanced front-end for Grep." - filename "igrep-1.10-pkg.tar.gz" - md5sum "ab371bae5cee68fb53afd5fd737cd462" - size 16903 - provides (igrep) - requires (dired xemacs-base efs) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(eterm - (standards-version 1.1 - version "1.13" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "os" - dump nil - description "Terminal emulation." - filename "eterm-1.13-pkg.tar.gz" - md5sum "ebd64834d12a2a3fc04bbb6f4dd836fa" - size 109184 - provides (eterm) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(viper - (standards-version 1.1 - version "1.36" - author-version "3.09" - date "2003-05-19" - build-date "2003-05-19" - maintainer "Michael Kifer " - distribution xemacs - priority low - category "standard" - dump nil - description "VI emulation support." - filename "viper-1.36-pkg.tar.gz" - md5sum "26b328fcd02c52acbf61bdc502daa489" - size 329897 - provides (viper-cmd viper-ex viper-init viper-keym viper-macs viper-mous viper-util viper) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(tpu - (standards-version 1.1 - version "1.12" - author-version "4.2X" - date "2000-10-05" - build-date "2001-01-15" - maintainer "Kevin Oberman " - distribution xemacs - priority medium - category "wp" - dump nil - description "DEC EDIT/TPU support." - filename "tpu-1.12-pkg.tar.gz" - md5sum "8ee6ca98afc9c18a1df013065c430f5e" - size 58850 - provides (tpu) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(textools - (standards-version 1.1 - version "1.14" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Miscellaneous TeX support." - filename "textools-1.14-pkg.tar.gz" - md5sum "baaa68caca74c6cc21f99798c0e8e0e5" - size 79510 - provides (bib-mode bibtex refer-to-bibtex) - requires (xemacs-base) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(texinfo - (standards-version 1.1 - version "1.24" - author-version "21.4" - date "2003-04-26" - build-date "2003-04-26" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "XEmacs TeXinfo support." - filename "texinfo-1.24-pkg.tar.gz" - md5sum "76c161778c926f90312f1596e75a9d76" - size 133715 - provides (makeinfo tex-mode texinfmt texinfo texnfo-tex texnfo-upd) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(reftex - (standards-version 1.1 - version "1.28" - author-version "4.19" - date "2002-08-29" - build-date "2002-08-29" - maintainer "Carsten Dominik " - distribution xemacs - priority medium - category "wp" - dump nil - description "Emacs support for LaTeX cross-references, citations.." - filename "reftex-1.28-pkg.tar.gz" - md5sum "8bf789e67715eb6eb77bec7cc25e37ed" - size 340634 - provides (reftex-auc reftex-cite reftex-dcr reftex-vcr reftex-global reftex-index reftex-parse reftex-ref reftex-sel reftex-toc reftex-vars reftex) - requires (fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(edt - (standards-version 1.1 - version "1.12" - author-version "21.5b1" - date "2001-07-14" - build-date "2001-07-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "DEC EDIT/EDT emulation." - filename "edt-1.12-pkg.tar.gz" - md5sum "0d7649d0f65d9de732918d756f5cf48b" - size 62441 - provides (edt) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(crisp - (standards-version 1.1 - version "1.12" - author-version "1.34" - date "1998-08-18" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "wp" - dump nil - description "Crisp/Brief emulation." - filename "crisp-1.12-pkg.tar.gz" - md5sum "30308c6e5fb14f621d53046894c8c180" - size 10075 - provides (crisp scroll-lock) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(auctex - (standards-version 1.1 - version "1.35" - author-version "11.13" - date "2003-01-03" - build-date "2003-01-03" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Basic TeX/LaTeX support." - filename "auctex-1.35-pkg.tar.gz" - md5sum "168e82155e152dab8c7c913bc9a4788b" - size 406466 - provides (auc-old auc-tex bib-cite font-latex latex multi-prompt tex-buf tex-info tex-jp tex-mik tex-site tex texmathp) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(vhdl - (standards-version 1.1 - version "1.17" - author-version "3.31.20" - date "2003-06-08" - build-date "2003-06-08" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Support for VHDL." - filename "vhdl-1.17-pkg.tar.gz" - md5sum "d228542a1db6f0f9552f3c239ea6723b" - size 273038 - provides (vhdl-mode) - requires (xemacs-base edit-utils c-support speedbar ps-print os-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(x-symbol - (standards-version 1.1 - version "1.05" - author-version "4.5.1" - date "2003-06-01" - build-date "2003-06-01" - maintainer "Steve Youngs " - distribution xemacs - priority high - category "standard" - dump nil - description "Semi WYSIWYG for LaTeX, HTML, etc, using additional fonts." - filename "x-symbol-1.05-pkg.tar.gz" - md5sum "cac33616d6c1b40258d7e49cf161c5f6" - size 682785 - provides (x-symbol-bib x-symbol-hooks x-symbol-image x-symbol-macs x-symbol-mule x-symbol-nomule x-symbol-sgml x-symbol-tex x-symbol-texi x-symbol-vars x-symbol-xmacs x-symbol) - requires (x-symbol xemacs-base auctex mail-lib) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(vc - (standards-version 1.1 - version "1.37" - author-version "21.4" - date "2003-01-18" - build-date "2003-01-18" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Version Control for Free systems." - filename "vc-1.37-pkg.tar.gz" - md5sum "a80fd60632202fd0fe566215e8c89451" - size 93512 - provides (vc vc-hooks) - requires (dired xemacs-base vc mail-lib ediff) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(vc-cc - (standards-version 1.1 - version "1.21" - author-version "21.5b6" - date "2002-06-04" - build-date "2002-06-04" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Version Control for ClearCase (UnFree) systems." - filename "vc-cc-1.21-pkg.tar.gz" - md5sum "eb7ad3f9407b32509fa95fa272476b7d" - size 94556 - provides (vc-cc vc-cc-hooks) - requires (dired xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sh-script - (standards-version 1.1 - version "1.17" - author-version "2.0e" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Support for editing shell scripts." - filename "sh-script-1.17-pkg.tar.gz" - md5sum "919e1c273b0eb05b17795f5f3382ef1c" - size 36945 - provides (sh-script executable) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(scheme - (standards-version 1.1 - version "1.13" - author-version "21.4" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Karl M. Hegbloom " - distribution xemacs - priority low - category "standard" - dump nil - description "Front-end support for Inferior Scheme." - filename "scheme-1.13-pkg.tar.gz" - md5sum "570e81d6079fb548b0b52d0e1f68aae2" - size 37048 - provides (scheme xscheme cmuscheme cmuscheme48) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(prog-modes - (standards-version 1.1 - version "1.79" - author-version "21.4" - date "2003-06-20" - build-date "2003-06-20" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Support for various programming languages." - filename "prog-modes-1.79-pkg.tar.gz" - md5sum "6f066a6b89b7f0bbdab99a8bade933bf" - size 657717 - provides (autoconf-mode awk-mode c-mode cvs diff-mode eiffel-mode icon javascript-mode ksh-mode m4-mode makefile mode-compile mode-compile-kill modula2 p4 php-mode postscript rexx-mode rpm-spec-mode simula-mode sql tcl teco verilog-mode) - requires (mail-lib xemacs-devel xemacs-base cc-mode fsf-compat edit-utils ediff emerge efs vc speedbar dired ilisp sh-script) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(idlwave - (standards-version 1.1 - version "1.28" - author-version "4.15" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Carsten Dominik " - distribution xemacs - priority medium - category "standard" - dump nil - description "Editing and Shell mode for the Interactive Data Language" - filename "idlwave-1.28-pkg.tar.gz" - md5sum "1e970d93e177fbdd3dff8d941bcc2dd0" - size 404471 - provides (idlw-rinfo idlwave-rinfo idlw-shell idlwave-shell idlw-toolbar idlwave-toolbar idlwave) - requires (fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(emerge - (standards-version 1.1 - version "1.09" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "prog" - dump nil - description "Another interface over GNU patch." - filename "emerge-1.09-pkg.tar.gz" - md5sum "231c8120d60da2c9ddd856510da2491c" - size 61043 - provides (emerge) - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ediff - (standards-version 1.1 - version "1.47" - author-version "2.75" - date "2003-05-19" - build-date "2003-05-19" - maintainer "Michael Kifer " - distribution xemacs - priority medium - category "standard" - dump nil - description "Interface over GNU patch." - filename "ediff-1.47-pkg.tar.gz" - md5sum "32276e3b47bb3bf1e461c7271091bbab" - size 305650 - provides (ediff-diff ediff-help ediff-hook ediff-init ediff-merg ediff-mult ediff-ptch ediff-tbar ediff-util ediff-vers ediff-wind ediff) - requires (pcl-cvs elib dired xemacs-base edebug prog-modes) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(debug - (standards-version 1.1 - version "1.16" - author-version "21.4" - date "2002-09-25" - build-date "2002-09-25" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "GUD, gdb, dbx debugging support." - filename "debug-1.16-pkg.tar.gz" - md5sum "1450bf0762934d079c1287d8baa5859c" - size 107641 - provides (dbx debug-toolbar gdb-highlight gdb gdbsrc gud history) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(c-support - (standards-version 1.1 - version "1.16" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "prog" - dump nil - description "Basic single-file add-ons for editing C code." - filename "c-support-1.16-pkg.tar.gz" - md5sum "047accf51457a041bf920c9563de1bf6" - size 70393 - provides (c-comment-edit cmacexp ctypes hideif hideshow) - requires (cc-mode xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(ada - (standards-version 1.1 - version "1.13" - author-version "2.27" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Ada language support." - filename "ada-1.13-pkg.tar.gz" - md5sum "2bed65b1357b24d371f27e4cca3fe352" - size 55694 - provides (ada-mode ada-stmt) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(cc-mode - (standards-version 1.1 - version "1.33" - author-version "5.28" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Martin Stjernholm " - distribution xemacs - priority medium - category "standard" - dump nil - description "C, C++ and Java language support." - filename "cc-mode-1.33-pkg.tar.gz" - md5sum "c711a14526fe18470934455f65c689d2" - size 261483 - provides (cc-bytecomp cc-align cc-cmds cc-compat cc-defs cc-engine cc-guess cc-langs cc-lobotomy cc-menus cc-mode-19 cc-mode cc-styles cc-vars) - requires (xemacs-base mail-lib) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(semantic - (standards-version 1.1 - version "1.17" - author-version "1.4.2" - date "2003-01-13" - build-date "2003-01-13" - maintainer "Eric M. Ludlam " - distribution xemacs - priority low - category "standard" - dump nil - description "Semantic bovinator (Yacc/Lex for XEmacs). Includes Senator." - filename "semantic-1.17-pkg.tar.gz" - md5sum "6c374b18834351d2939683c5c62b44a6" - size 443557 - provides (document-vars document semantic-analyze semantic-bnf semantic-c semantic-cb semantic-chart semantic-ctxt semantic-el semantic-example semantic-ia-sb semantic-ia semantic-imenu semantic-java semantic-load semantic-make semantic-sb semantic-scm semantic-skel semantic-texi semantic-util-modes semantic-util semantic semanticdb senator sformat working) - requires (eieio xemacs-base xemacs-devel edit-utils speedbar texinfo fsf-compat cc-mode edebug) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(misc-games - (standards-version 1.1 - version "1.16" - author-version "21.4" - date "2002-12-06" - build-date "2002-12-06" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Other amusements and diversions." - filename "misc-games-1.16-pkg.tar.gz" - md5sum "2aaccb449220bcd0388165e07592764e" - size 166197 - provides (decipher gomoku hanoi life morse rot13) - requires (xemacs-base) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mine - (standards-version 1.1 - version "1.14" - author-version "1.9" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "games" - dump nil - description "Minehunt Game." - filename "mine-1.14-pkg.tar.gz" - md5sum "ebe471b68642906786db139d402002c7" - size 66727 - provides (xmine) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(games - (standards-version 1.1 - version "1.14" - author-version "1.04" - date "2003-06-15" - build-date "2003-06-15" - maintainer "Glynn Clements " - distribution xemacs - priority low - category "standard" - dump nil - description "Tetris, Sokoban, and Snake." - filename "games-1.14-pkg.tar.gz" - md5sum "5c00d86c1f959d32bf12da6f78fd1fcf" - size 37132 - provides (gamegrid snake tetris sokoban) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(cookie - (standards-version 1.1 - version "1.14" - author-version "21.5b5" - date "2002-03-25" - build-date "2002-03-25" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Spook and Yow (Zippy quotes)." - filename "cookie-1.14-pkg.tar.gz" - md5sum "50581960785fb3949faabaae49896c32" - size 34543 - provides (cookie1 yow) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(bbdb - (standards-version 1.1 - version "1.23" - author-version "2.34" - date "2003-05-18" - build-date "2003-05-18" - maintainer "Ronan Waide " - distribution xemacs - priority medium - category "standard" - dump nil - description "The Big Brother Data Base" - filename "bbdb-1.23-pkg.tar.gz" - md5sum "6cced769e1bd48d5a571b654958cd35d" - size 374355 - provides (bbdb-com bbdb-ftp bbdb-gnus bbdb-gui bbdb-hooks bbdb-merge bbdb-mhe bbdb-migrate bbdb-print bbdb-reportmail bbdb-rmail bbdb-sc bbdb-snarf bbdb-srv bbdb-vm bbdb-w3 bbdb-whois bbdb-xemacs bbdb) - requires (bbdb edit-utils gnus mh-e rmail supercite vm tm apel mail-lib xemacs-base w3 fsf-compat eterm sh-script net-utils os-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(zenirc - (standards-version 1.1 - version "1.13" - author-version "2.112" - date "2002-01-07" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "ZENIRC IRC Client." - filename "zenirc-1.13-pkg.tar.gz" - md5sum "38200c80672a32056426ed32c09473cf" - size 276760 - provides (zenirc-18 zenirc-8ball zenirc-away zenirc-bork zenirc-color zenirc-command-queue zenirc-complete zenirc-ctcp-flood zenirc-dcc zenirc-doto zenirc-fill zenirc-finnish zenirc-format zenirc-fortran zenirc-french zenirc-history zenirc-ignore zenirc-iwantop zenirc-klingon zenirc-latin zenirc-meditate zenirc-netsplit zenirc-notify zenirc-oink zenirc-ojnk zenirc-pjg zenirc-popup zenirc-random-away zenirc-random-nick zenirc-signal zenirc-stamp zenirc-swedish zenirc-trigger zenirc-yow-filter zenirc-yow zenirc) - requires (zenirc) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mew - (standards-version 1.1 - version "1.17" - author-version "1.94.2" - date "2002-03-25" - build-date "2002-03-25" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Messaging in an Emacs World." - filename "mew-1.17-pkg.tar.gz" - md5sum "03fa0583b534322d0375901796d22ec5" - size 654737 - provides (mew-addrbook mew-attach mew-bq mew-cache mew-complete mew-decode mew-demo mew-draft mew-encode mew-env mew-ext mew-fib mew-func mew-header mew-highlight mew-lang-jp mew-mark mew-message mew-mime mew-minibuf mew-mule mew-mule0 mew-mule2 mew-mule3 mew-os2 mew-pgp mew-pick mew-refile mew-scan mew-sort mew-summary mew-syntax mew-temacs mew-unix mew-vars mew-virtual mew-win32 mew-xemacs mew) - requires (mew w3 efs mail-lib xemacs-base fsf-compat) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(tm - (standards-version 1.1 - version "1.36" - author-version "21.5b13" - date "2003-05-14" - build-date "2003-05-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Emacs MIME support. Not needed for gnus >= 5.8.0" - filename "tm-1.36-pkg.tar.gz" - md5sum "03830180796f04f085bcec5a62e2d17a" - size 334020 - provides (char-util cless gnus-art-mime gnus-charset gnus-mime gnus-sum-mime latex-math-symbol mel-b mel-g mel-q mel-u mel message-mime mime-setup mu-bbdb mu-cite range sc-setup signature texi-util tl-atype tl-list tl-misc tl-num tl-seq tl-str tm-bbdb tm-def tm-edit-mc tm-edit tm-ew-d tm-ew-e tm-file tm-ftp tm-html tm-image tm-latex tm-mail tm-mh-e tm-parse tm-partial tm-pgp tm-play tm-rmail tm-setup tm-tar tm-text tm-view tm-vm tmh-comp) - requires (gnus mh-e rmail vm mailcrypt mail-lib apel xemacs-base fsf-compat sh-script net-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(gnus - (standards-version 1.1 - version "1.71" - author-version "5.10.2" - date "2003-05-18" - build-date "2003-05-18" - maintainer "Steve Youngs " - distribution xemacs - priority medium - category "standard" - dump nil - description "The Gnus Newsreader and Mailreader." - filename "gnus-1.71-pkg.tar.gz" - md5sum "87a26e70ef2632dc11831964c5b9267b" - size 3282718 - provides (binhex canlock compface deuglify earcon flow-fill format-spec gnus-agent gnus-art gnus-async gnus-audio gnus-bcklg gnus-cache gnus-cite gnus-cus gnus-delay gnus-demon gnus-diary gnus-dired gnus-draft gnus-dup gnus-eform gnus-ems gnus-fun gnus-gl gnus-group gnus-int gnus-kill gnus-logic gnus-mh gnus-ml gnus-mlspl gnus-move gnus-msg gnus-nocem gnus-picon gnus-range gnus-registry gnus-salt gnus-score gnus-setup gnus-sieve gnus-soup gnus-spec gnus-srvr gnus-start gnus-sum gnus-topic gnus-undo gnus-util gnus-uu gnus-vm gnus-win gnus-xmas gnus ietf-drums imap mail-parse mail-prsvr mail-source mailcap message messagexmas messcompat mm-bodies mm-decode mm-encode mm-extern mm-partial mm-url mm-util mm-uu mm-view mml-sec mml-smime mml mml1991 mml2015 nnagent nnbabyl nndb nndiary nndir nndoc nndraft nneething nnfolder nngateway nnheader nnheaderxm nnimap nnkiboze nnlistserv nnmail nnmaildir nnmbox nnmh nnml nnnil nnoo nnrss nnslashdot nnsoup nnspool nntp nnultimate nnvirtual nnwarchive nnweb nnwfm parse-time qp rfc1843 rfc2045 rfc2047 rfc2231 score-mode smiley smime spam-report spam-stat spam time-date utf7 uudecode webmail yenc gnus-idna gpg-ring gpg hashcash vcard) - requires (gnus w3 mh-e mailcrypt rmail eterm mail-lib xemacs-base fsf-compat ecrypto tm apel pgg net-utils sh-script os-utils dired sieve sasl) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(rmail - (standards-version 1.1 - version "1.13" - author-version "21.5b4" - date "2002-01-13" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "An obsolete Emacs mailer." - filename "rmail-1.13-pkg.tar.gz" - md5sum "4da12b01ea3735412f95edeb2a2bd0bd" - size 96265 - provides (rmail-kill rmail-xemacs rmail rmailsort) - requires (tm apel mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mailcrypt - (standards-version 1.1 - version "2.12" - author-version "3.5.8" - date "2002-10-07" - build-date "2002-10-07" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Support for messaging encryption with PGP." - filename "mailcrypt-2.12-pkg.tar.gz" - md5sum "a82276fc399b6a72d8769d6e3bcc7e41" - size 153873 - provides (expect mailcrypt) - requires (mail-lib fsf-compat xemacs-base cookie gnus mh-e rmail vm) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(supercite - (standards-version 1.1 - version "1.19" - author-version "3.55x3" - date "2002-01-07" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "An Emacs citation tool for News & Mail messages." - filename "supercite-1.19-pkg.tar.gz" - md5sum "8f6767ea4e03306d1e5553501ed7cd2e" - size 100881 - provides (supercite) - requires (mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(mh-e - (standards-version 1.1 - version "1.23" - author-version "7.3" - date "2003-05-19" - build-date "2003-05-19" - maintainer "Steve Youngs " - distribution xemacs - priority low - category "standard" - dump nil - description "Front end support for MH." - filename "mh-e-1.23-pkg.tar.gz" - md5sum "d7d99f142797bbe3fba206d6932a1e75" - size 551037 - provides (mh-alias mh-comp mh-customize mh-e mh-funcs mh-identity mh-inc mh-index mh-junk mh-loaddefs mh-mime mh-pick mh-seq mh-speed mh-unit mh-utils mh-xemacs-compat mh-xemacs-icons) - requires (gnus mail-lib xemacs-base speedbar rmail tm apel sh-script fsf-compat xemacs-devel net-utils eterm os-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(gnats - (standards-version 1.1 - version "1.15" - author-version "3.101" - date "2002-06-27" - build-date "2002-06-27" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "XEmacs bug reports." - filename "gnats-1.15-pkg.tar.gz" - md5sum "9503a79e2e396eb13151aec7eadf561b" - size 189524 - provides (gnats gnats-admin send-pr) - requires (mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(footnote - (standards-version 1.1 - version "1.15" - author-version "0.18x" - date "2002-04-24" - build-date "2002-04-24" - maintainer "SL Baur " - distribution xemacs - priority low - category "standard" - dump nil - description "Footnoting in mail message editing modes." - filename "footnote-1.15-pkg.tar.gz" - md5sum "1cbe1e587881611006d9a8fc82be3be1" - size 21917 - provides (footnote-cyrillic footnote-greek footnote-han footnote-hebrew footnote-kana footnote) - requires (mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(eudc - (standards-version 1.1 - version "1.38" - author-version "1.32" - date "2003-05-18" - build-date "2003-05-18" - maintainer "Oscar Figueiredo " - distribution xemacs - priority low - category "standard" - dump nil - description "Emacs Unified Directory Client (LDAP, PH)." - filename "eudc-1.38-pkg.tar.gz" - md5sum "44f701aa6b6460eb766e994a6f0f3072" - size 79327 - provides (eudc eudc-vars eudc-hotlist eudc-export eudc-bob eudcb-ldap eudcb-ph eudcb-bbdb) - requires (fsf-compat xemacs-base bbdb mail-lib gnus rmail tm apel eterm sh-script net-utils) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(net-utils - (standards-version 1.1 - version "1.32" - author-version "21.4" - date "2003-05-02" - build-date "2003-05-02" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "Miscellaneous Networking Utilities." - filename "net-utils-1.32-pkg.tar.gz" - md5sum "0c756dbe87fac94fda8c175283fc7f2c" - size 137374 - provides (ilisp-browse-cltl2 xemacsbug feedmail metamail net-utils rcompile shadowfile webjump webster-www dig dns xml) - requires (bbdb w3 efs mail-lib xemacs-base fsf-compat eterm sh-script gnus rmail tm apel) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(w3 - (standards-version 1.1 - version "1.28" - author-version "4.0pre47" - date "2003-01-13" - build-date "2003-01-13" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "A Web browser." - filename "w3-1.28-pkg.tar.gz" - md5sum "67c77722bdb50d6ab6287d3994f91b09" - size 695206 - provides (css devices w3-auto dsssl-flow dsssl font images mm mule-sysdp socks ssl urlauth url-cache url-cookie url-file url-gopher url-gw url-http url-ldap url-mail url-misc url-news url-ns url-parse url-vars url w3-about w3-auto w3-cfg w3-cus w3-display w3-emacs19 w3-e19 w3-e20 w3-elisp w3-emulate w3-forms w3-hot w3-hotindex w3-imap w3-java w3-jscript w3-keyword w3-latex w3-menu w3-mouse w3-parse w3-print w3-props w3-script w3-structure w3-speak w3-style w3-sysdp w3-toolbar w3-vars w3-widget w3-xemacs w3-xemac w3) - requires (w3 mail-lib xemacs-base ecrypto) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(vm - (standards-version 1.1 - version "7.14" - author-version "7.14" - date "2002-06-08" - build-date "2002-06-08" - maintainer "Kyle Jones " - distribution xemacs - priority medium - category "standard" - dump nil - description "An Emacs mailer." - filename "vm-7.14-pkg.tar.gz" - md5sum "18c68c9165f4877a00f0fea395dc4aa3" - size 793198 - provides (tapestry vm-byteopts vm-delete vm-digest vm-easymenu vm-edit vm-folder vm-imap vm-license vm-macro vm-mark vm-menu vm-message vm-mime vm-minibuf vm-misc vm-motion vm-mouse vm-page vm-pop vm-reply vm-save vm-search vm-sort vm-startup vm-summary vm-thread vm-toolbar vm-undo vm-user vm-vars vm vm-version vm-virtual vm-window) - requires (mail-lib xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sounds-wav - (standards-version 1.1 - version "1.10" - author-version "21.1" - date "2000-05-23" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "libs" - dump nil - description "XEmacs Microsoft sound files." - filename "sounds-wav-1.10-pkg.tar.gz" - md5sum "89dff9f3b8e1aaaa19f000035e3aa199" - size 149162 - provides () - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(sounds-au - (standards-version 1.1 - version "1.10" - author-version "21.1" - date "2000-05-23" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "libs" - dump nil - description "XEmacs Sun sound files." - filename "sounds-au-1.10-pkg.tar.gz" - md5sum "256e09c0570a19ae545350681bacaf3e" - size 126306 - provides () - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(xemacs-devel - (standards-version 1.1 - version "1.55" - author-version "21.4" - date "2003-05-18" - build-date "2003-05-18" - maintainer "XEmacs Development Team " - distribution xemacs - priority medium - category "standard" - dump nil - description "Emacs Lisp developer support." - filename "xemacs-devel-1.55-pkg.tar.gz" - md5sum "6fe0e1b869502c94adaa9e5d6623d5f3" - size 233111 - provides (checkdoc docref eldoc elp eval-expr find-func hide-copyleft ielm patcher pp trace patch-keywords) - requires (xemacs-base ispell mail-lib gnus rmail tm apel sh-script net-utils eterm) - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(tooltalk - (standards-version 1.1 - version "1.13" - author-version "21.1" - date "2000-10-05" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "libs" - dump nil - description "Support for building with Tooltalk." - filename "tooltalk-1.13-pkg.tar.gz" - md5sum "3f01dab216a3bc318d11f362d22ea89c" - size 9301 - provides () - requires () - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(elib - (standards-version 1.1 - version "1.10" - author-version "1.0" - date "2002-01-07" - build-date "2002-01-14" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "Portable Emacs Lisp utilities library." - filename "elib-1.10-pkg.tar.gz" - md5sum "01deb690554da8c3f7c97e0ae170ae69" - size 73309 - provides (avltree bintree cookie dll elib-node queue-f queue-m read stack-f stack-m string) - requires () - type single -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(edebug - (standards-version 1.1 - version "1.18" - author-version "21.4" - date "2003-06-01" - build-date "2003-06-01" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "standard" - dump nil - description "An Emacs Lisp debugger." - filename "edebug-1.18-pkg.tar.gz" - md5sum "ea33ebf474676aff1a782fa9abc0b958" - size 114099 - provides (edebug cl-read cust-print eval-reg cl-specs) - requires (xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(Sun - (standards-version 1.1 - version "1.13" - author-version "21.1" - date "1998-07-25" - build-date "2001-01-15" - maintainer "XEmacs Development Team " - distribution xemacs - priority low - category "libs" - dump nil - description "Support for Sparcworks." - filename "Sun-1.13-pkg.tar.gz" - md5sum "455b7e1c3564563687e36ab53352ba76" - size 63836 - provides (sccs eos-browser eos-common eos-debugger eos-debugger eos-editor eos-init eos-load eos-menubar eos-toolbar sunpro) - requires (cc-mode xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(apel - (standards-version 1.1 - version "1.26" - author-version "10.2" - date "2003-01-03" - build-date "2003-01-03" - maintainer "XEmacs Development Team " - distribution xemacs - priority high - category "standard" - dump nil - description "A Portable Emacs Library. Used by XEmacs MIME support." - filename "apel-1.26-pkg.tar.gz" - md5sum "f8981e7b041e5f493d30fbd82b15f831" - size 108340 - provides (atype emu-20 emu-e19 emu-x20 emu-xemacs emu file-detect filename install mule-caesar path-util richtext std11-parse std11 tinyrich) - requires (fsf-compat xemacs-base) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(efs - (standards-version 1.0 - version "1.29" - author-version "1.20" - date "2002-04-24" - build-date "2002-04-24" - maintainer "Mike Sperber " - distribution stable - priority medium - category "standard" - dump nil - description "Treat files on remote systems the same as local files." - filename "efs-1.29-pkg.tar.gz" - md5sum "8c2c6c00cfbdc5f8d64ad54ddfb731df" - size 371905 - provides (efs) - requires (xemacs-base dired) - type regular -)) -)) -;;;@@@ -(package-get-update-base-entry (quote -(dired - (standards-version 1.0 - version "1.13" - author-version "7.10" - date "2003-01-03" - build-date "2003-01-03" - maintainer "Mike Sperber " - distribution stable - priority medium - category "standard" - dump nil - description "Manage file systems." - filename "dired-1.13-pkg.tar.gz" - md5sum "bedcfcb1c8c9829663f0d66d6612154e" - size 196323 - provides (diff dired) - requires (xemacs-base prog-modes) - type regular -)) -)) -;;;@@@ -;; Package Index file ends here diff -u -r -N xemacs-21.4.14/info/cl.info xemacs-21.4.15/info/cl.info --- xemacs-21.4.14/info/cl.info 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info 2004-02-02 22:01:03.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. +This is ../info/cl.info, produced by makeinfo version 4.6 from cl.texi. INFO-DIR-SECTION XEmacs Editor START-INFO-DIR-ENTRY @@ -27,16 +27,5041 @@ the original English.  -Indirect: -cl.info-1: 1164 -cl.info-2: 46305 -cl.info-3: 89086 -cl.info-4: 137809 -cl.info-5: 175805 -cl.info-6: 218388 +File: cl.info, Node: Top, Next: Overview, Up: (dir) + +Common Lisp Extensions +********************** + +This document describes a set of Emacs Lisp facilities borrowed from +Common Lisp. All the facilities are described here in detail; for more +discussion and examples, Guy L. Steele's `Common Lisp, the Language', +second edition, is the definitive book on Common Lisp. While this +document does not assume any prior knowledge of Common Lisp, it does +assume a basic familiarity with Emacs Lisp. + +* Menu: + +* Overview:: Installation, usage, etc. +* Program Structure:: Arglists, `eval-when', `defalias' +* Predicates:: `typep', `eql', and `equalp' +* Control Structure:: `setf', `when', `do', `loop', etc. +* Macros:: Destructuring, `define-compiler-macro' +* Declarations:: `proclaim', `declare', etc. +* Symbols:: Property lists, `gensym' +* Numbers:: Predicates, functions, random numbers +* Sequences:: Mapping, functions, searching, sorting +* Lists:: `cadr', `sublis', `member*', `assoc*', etc. +* Hash Tables:: `make-hash-table', `gethash', etc. +* Structures:: `defstruct' +* Assertions:: `check-type', `assert', `ignore-errors'. + +* Efficiency Concerns:: Hints and techniques +* Common Lisp Compatibility:: All known differences with Steele +* Old CL Compatibility:: All known differences with old cl.el +* Porting Common Lisp:: Hints for porting Common Lisp code + +* Function Index:: +* Variable Index:: + + +File: cl.info, Node: Overview, Next: Program Structure, Prev: Top, Up: Top + +Overview +******** + +Common Lisp is a huge language, and Common Lisp systems tend to be +massive and extremely complex. Emacs Lisp, by contrast, is rather +minimalist in the choice of Lisp features it offers the programmer. As +Emacs Lisp programmers have grown in number, and the applications they +write have grown more ambitious, it has become clear that Emacs Lisp +could benefit from many of the conveniences of Common Lisp. + + The "CL" package adds a number of Common Lisp functions and control +structures to Emacs Lisp. While not a 100% complete implementation of +Common Lisp, "CL" adds enough functionality to make Emacs Lisp +programming significantly more convenient. + + Some Common Lisp features have been omitted from this package for +various reasons: + + * Some features are too complex or bulky relative to their benefit + to Emacs Lisp programmers. CLOS and Common Lisp streams are fine + examples of this group. + + * Other features cannot be implemented without modification to the + Emacs Lisp interpreter itself, such as multiple return values, + lexical scoping, case-insensitive symbols, and complex numbers. + The "CL" package generally makes no attempt to emulate these + features. + + * Some features conflict with existing things in Emacs Lisp. For + example, Emacs' `assoc' function is incompatible with the Common + Lisp `assoc'. In such cases, this package usually adds the suffix + `*' to the function name of the Common Lisp version of the + function (e.g., `assoc*'). + + The package described here was written by Dave Gillespie, +`daveg@synaptics.com'. It is a total rewrite of the original 1986 +`cl.el' package by Cesar Quiroz. Most features of the Quiroz package +have been retained; any incompatibilities are noted in the descriptions +below. Care has been taken in this version to ensure that each +function is defined efficiently, concisely, and with minimal impact on +the rest of the Emacs environment. + +* Menu: + +* Usage:: How to use the CL package +* Organization:: The package's five component files +* Installation:: Compiling and installing CL +* Naming Conventions:: Notes on CL function names + + +File: cl.info, Node: Usage, Next: Organization, Prev: Overview, Up: Overview + +Usage +===== + +Lisp code that uses features from the "CL" package should include at +the beginning: + + (require 'cl) + +If you want to ensure that the new (Gillespie) version of "CL" is the +one that is present, add an additional `(require 'cl-19)' call: + + (require 'cl) + (require 'cl-19) + +The second call will fail (with "`cl-19.el' not found") if the old +`cl.el' package was in use. + + It is safe to arrange to load "CL" at all times, e.g., in your +`.emacs' file. But it's a good idea, for portability, to `(require +'cl)' in your code even if you do this. + + +File: cl.info, Node: Organization, Next: Installation, Prev: Usage, Up: Overview + +Organization +============ + +The Common Lisp package is organized into four files: + +`cl.el' + This is the "main" file, which contains basic functions and + information about the package. This file is relatively + compact--about 700 lines. + +`cl-extra.el' + This file contains the larger, more complex or unusual functions. + It is kept separate so that packages which only want to use Common + Lisp fundamentals like the `cadr' function won't need to pay the + overhead of loading the more advanced functions. + +`cl-seq.el' + This file contains most of the advanced functions for operating on + sequences or lists, such as `delete-if' and `assoc*'. + +`cl-macs.el' + This file contains the features of the packages which are macros + instead of functions. Macros expand when the caller is compiled, + not when it is run, so the macros generally only need to be + present when the byte-compiler is running (or when the macros are + used in uncompiled code such as a `.emacs' file). Most of the + macros of this package are isolated in `cl-macs.el' so that they + won't take up memory unless you are compiling. + + The file `cl.el' includes all necessary `autoload' commands for the +functions and macros in the other three files. All you have to do is +`(require 'cl)', and `cl.el' will take care of pulling in the other +files when they are needed. + + There is another file, `cl-compat.el', which defines some routines +from the older `cl.el' package that are no longer present in the new +package. This includes internal routines like `setelt' and +`zip-lists', deprecated features like `defkeyword', and an emulation of +the old-style multiple-values feature. *Note Old CL Compatibility::. + + +File: cl.info, Node: Installation, Next: Naming Conventions, Prev: Organization, Up: Overview + +Installation +============ + +Installation of the "CL" package is simple: Just put the byte-compiled +files `cl.elc', `cl-extra.elc', `cl-seq.elc', `cl-macs.elc', and +`cl-compat.elc' into a directory on your `load-path'. + + There are no special requirements to compile this package: The files +do not have to be loaded before they are compiled, nor do they need to +be compiled in any particular order. + + You may choose to put the files into your main `lisp/' directory, +replacing the original `cl.el' file there. Or, you could put them into +a directory that comes before `lisp/' on your `load-path' so that the +old `cl.el' is effectively hidden. + + Also, format the `cl.texinfo' file and put the resulting Info files +in the `info/' directory or another suitable place. + + You may instead wish to leave this package's components all in their +own directory, and then add this directory to your `load-path' and +(Emacs 19 only) `Info-directory-list'. Add the directory to the front +of the list so the old "CL" package and its documentation are hidden. + + +File: cl.info, Node: Naming Conventions, Prev: Installation, Up: Overview + +Naming Conventions +================== + +Except where noted, all functions defined by this package have the same +names and calling conventions as their Common Lisp counterparts. + + Following is a complete list of functions whose names were changed +from Common Lisp, usually to avoid conflicts with Emacs. In each case, +a `*' has been appended to the Common Lisp name to obtain the Emacs +name: + + defun* defsubst* defmacro* function* + member* assoc* rassoc* remove* + delete* mapcar* sort* floor* + ceiling* truncate* round* mod* + rem* random* + + Internal function and variable names in the package are prefixed by +`cl-'. Here is a complete list of functions _not_ prefixed by `cl-' +which were not taken from Common Lisp: + + member delete remove remq + rassoc floatp-safe lexical-let lexical-let* + callf callf2 letf letf* + defsubst* defalias add-hook eval-when-compile + +(Most of these are Emacs 19 features provided to Emacs 18 users, or +introduced, like `remq', for reasons of symmetry with similar features.) + + The following simple functions and macros are defined in `cl.el'; +they do not cause other components like `cl-extra' to be loaded. + + eql floatp-safe abs endp + evenp oddp plusp minusp + last butlast nbutlast caar .. cddddr + list* ldiff rest first .. tenth + member [1] copy-list subst mapcar* [2] + adjoin [3] acons pairlis when + unless pop [4] push [4] pushnew [3,4] + incf [4] decf [4] proclaim declaim + add-hook + +[1] This is the Emacs 19-compatible function, not `member*'. + +[2] Only for one sequence argument or two list arguments. + +[3] Only if `:test' is `eq', `equal', or unspecified, and `:key' is not +used. + +[4] Only when PLACE is a plain variable name. + + +File: cl.info, Node: Program Structure, Next: Predicates, Prev: Overview, Up: Top + +Program Structure +***************** + +This section describes features of the "CL" package which have to do +with programs as a whole: advanced argument lists for functions, and +the `eval-when' construct. + +* Menu: + +* Argument Lists:: `&key', `&aux', `defun*', `defmacro*'. +* Time of Evaluation:: The `eval-when' construct. +* Function Aliases:: The `defalias' function. + + +File: cl.info, Node: Argument Lists, Next: Time of Evaluation, Prev: Program Structure, Up: Program Structure + +Argument Lists +============== + +Emacs Lisp's notation for argument lists of functions is a subset of +the Common Lisp notation. As well as the familiar `&optional' and +`&rest' markers, Common Lisp allows you to specify default values for +optional arguments, and it provides the additional markers `&key' and +`&aux'. + + Since argument parsing is built-in to Emacs, there is no way for +this package to implement Common Lisp argument lists seamlessly. +Instead, this package defines alternates for several Lisp forms which +you must use if you need Common Lisp argument lists. + + - Special Form: defun* name arglist body... + This form is identical to the regular `defun' form, except that + ARGLIST is allowed to be a full Common Lisp argument list. Also, + the function body is enclosed in an implicit block called NAME; + *note Blocks and Exits::. + + - Special Form: defsubst* name arglist body... + This is just like `defun*', except that the function that is + defined is automatically proclaimed `inline', i.e., calls to it + may be expanded into in-line code by the byte compiler. This is + analogous to the `defsubst' form in Emacs 19; `defsubst*' uses a + different method (compiler macros) which works in all version of + Emacs, and also generates somewhat more efficient inline + expansions. In particular, `defsubst*' arranges for the + processing of keyword arguments, default values, etc., to be done + at compile-time whenever possible. + + - Special Form: defmacro* name arglist body... + This is identical to the regular `defmacro' form, except that + ARGLIST is allowed to be a full Common Lisp argument list. The + `&environment' keyword is supported as described in Steele. The + `&whole' keyword is supported only within destructured lists (see + below); top-level `&whole' cannot be implemented with the current + Emacs Lisp interpreter. The macro expander body is enclosed in an + implicit block called NAME. + + - Special Form: function* symbol-or-lambda + This is identical to the regular `function' form, except that if + the argument is a `lambda' form then that form may use a full + Common Lisp argument list. + + Also, all forms (such as `defsetf' and `flet') defined in this +package that include ARGLISTs in their syntax allow full Common Lisp +argument lists. + + Note that it is _not_ necessary to use `defun*' in order to have +access to most "CL" features in your function. These features are +always present; `defun*''s only difference from `defun' is its more +flexible argument lists and its implicit block. + + The full form of a Common Lisp argument list is + + (VAR... + &optional (VAR INITFORM SVAR)... + &rest VAR + &key ((KEYWORD VAR) INITFORM SVAR)... + &aux (VAR INITFORM)...) + + Each of the five argument list sections is optional. The SVAR, +INITFORM, and KEYWORD parts are optional; if they are omitted, then +`(VAR)' may be written simply `VAR'. + + The first section consists of zero or more "required" arguments. +These arguments must always be specified in a call to the function; +there is no difference between Emacs Lisp and Common Lisp as far as +required arguments are concerned. + + The second section consists of "optional" arguments. These +arguments may be specified in the function call; if they are not, +INITFORM specifies the default value used for the argument. (No +INITFORM means to use `nil' as the default.) The INITFORM is evaluated +with the bindings for the preceding arguments already established; `(a +&optional (b (1+ a)))' matches one or two arguments, with the second +argument defaulting to one plus the first argument. If the SVAR is +specified, it is an auxiliary variable which is bound to `t' if the +optional argument was specified, or to `nil' if the argument was +omitted. If you don't use an SVAR, then there will be no way for your +function to tell whether it was called with no argument, or with the +default value passed explicitly as an argument. + + The third section consists of a single "rest" argument. If more +arguments were passed to the function than are accounted for by the +required and optional arguments, those extra arguments are collected +into a list and bound to the "rest" argument variable. Common Lisp's +`&rest' is equivalent to that of Emacs Lisp. Common Lisp accepts +`&body' as a synonym for `&rest' in macro contexts; this package +accepts it all the time. + + The fourth section consists of "keyword" arguments. These are +optional arguments which are specified by name rather than positionally +in the argument list. For example, + + (defun* foo (a &optional b &key c d (e 17))) + +defines a function which may be called with one, two, or more +arguments. The first two arguments are bound to `a' and `b' in the +usual way. The remaining arguments must be pairs of the form `:c', +`:d', or `:e' followed by the value to be bound to the corresponding +argument variable. (Symbols whose names begin with a colon are called +"keywords", and they are self-quoting in the same way as `nil' and `t'.) + + For example, the call `(foo 1 2 :d 3 :c 4)' sets the five arguments +to 1, 2, 4, 3, and 17, respectively. If the same keyword appears more +than once in the function call, the first occurrence takes precedence +over the later ones. Note that it is not possible to specify keyword +arguments without specifying the optional argument `b' as well, since +`(foo 1 :c 2)' would bind `b' to the keyword `:c', then signal an error +because `2' is not a valid keyword. + + If a KEYWORD symbol is explicitly specified in the argument list as +shown in the above diagram, then that keyword will be used instead of +just the variable name prefixed with a colon. You can specify a +KEYWORD symbol which does not begin with a colon at all, but such +symbols will not be self-quoting; you will have to quote them +explicitly with an apostrophe in the function call. + + Ordinarily it is an error to pass an unrecognized keyword to a +function, e.g., `(foo 1 2 :c 3 :goober 4)'. You can ask Lisp to ignore +unrecognized keywords, either by adding the marker `&allow-other-keys' +after the keyword section of the argument list, or by specifying an +`:allow-other-keys' argument in the call whose value is non-`nil'. If +the function uses both `&rest' and `&key' at the same time, the "rest" +argument is bound to the keyword list as it appears in the call. For +example: + + (defun* find-thing (thing &rest rest &key need &allow-other-keys) + (or (apply 'member* thing thing-list :allow-other-keys t rest) + (if need (error "Thing not found")))) + +This function takes a `:need' keyword argument, but also accepts other +keyword arguments which are passed on to the `member*' function. +`allow-other-keys' is used to keep both `find-thing' and `member*' from +complaining about each others' keywords in the arguments. + + As a (significant) performance optimization, this package implements +the scan for keyword arguments by calling `memq' to search for keywords +in a "rest" argument. Technically speaking, this is incorrect, since +`memq' looks at the odd-numbered values as well as the even-numbered +keywords. The net effect is that if you happen to pass a keyword symbol +as the _value_ of another keyword argument, where that keyword symbol +happens to equal the name of a valid keyword argument of the same +function, then the keyword parser will become confused. This minor bug +can only affect you if you use keyword symbols as general-purpose data +in your program; this practice is strongly discouraged in Emacs Lisp. + + The fifth section of the argument list consists of "auxiliary +variables". These are not really arguments at all, but simply +variables which are bound to `nil' or to the specified INITFORMS during +execution of the function. There is no difference between the +following two functions, except for a matter of stylistic taste: + + (defun* foo (a b &aux (c (+ a b)) d) + BODY) + + (defun* foo (a b) + (let ((c (+ a b)) d) + BODY)) + + Argument lists support "destructuring". In Common Lisp, +destructuring is only allowed with `defmacro'; this package allows it +with `defun*' and other argument lists as well. In destructuring, any +argument variable (VAR in the above diagram) can be replaced by a list +of variables, or more generally, a recursive argument list. The +corresponding argument value must be a list whose elements match this +recursive argument list. For example: + + (defmacro* dolist ((var listform &optional resultform) + &rest body) + ...) + + This says that the first argument of `dolist' must be a list of two +or three items; if there are other arguments as well as this list, they +are stored in `body'. All features allowed in regular argument lists +are allowed in these recursive argument lists. In addition, the clause +`&whole VAR' is allowed at the front of a recursive argument list. It +binds VAR to the whole list being matched; thus `(&whole all a b)' +matches a list of two things, with `a' bound to the first thing, `b' +bound to the second thing, and `all' bound to the list itself. (Common +Lisp allows `&whole' in top-level `defmacro' argument lists as well, +but Emacs Lisp does not support this usage.) + + One last feature of destructuring is that the argument list may be +dotted, so that the argument list `(a b . c)' is functionally +equivalent to `(a b &rest c)'. + + If the optimization quality `safety' is set to 0 (*note +Declarations::), error checking for wrong number of arguments and +invalid keyword arguments is disabled. By default, argument lists are +rigorously checked. + + +File: cl.info, Node: Time of Evaluation, Next: Function Aliases, Prev: Argument Lists, Up: Program Structure + +Time of Evaluation +================== + +Normally, the byte-compiler does not actually execute the forms in a +file it compiles. For example, if a file contains `(setq foo t)', the +act of compiling it will not actually set `foo' to `t'. This is true +even if the `setq' was a top-level form (i.e., not enclosed in a +`defun' or other form). Sometimes, though, you would like to have +certain top-level forms evaluated at compile-time. For example, the +compiler effectively evaluates `defmacro' forms at compile-time so that +later parts of the file can refer to the macros that are defined. + + - Special Form: eval-when (situations...) forms... + This form controls when the body FORMS are evaluated. The + SITUATIONS list may contain any set of the symbols `compile', + `load', and `eval' (or their long-winded ANSI equivalents, + `:compile-toplevel', `:load-toplevel', and `:execute'). + + The `eval-when' form is handled differently depending on whether + or not it is being compiled as a top-level form. Specifically, it + gets special treatment if it is being compiled by a command such + as `byte-compile-file' which compiles files or buffers of code, + and it appears either literally at the top level of the file or + inside a top-level `progn'. + + For compiled top-level `eval-when's, the body FORMS are executed + at compile-time if `compile' is in the SITUATIONS list, and the + FORMS are written out to the file (to be executed at load-time) if + `load' is in the SITUATIONS list. + + For non-compiled-top-level forms, only the `eval' situation is + relevant. (This includes forms executed by the interpreter, forms + compiled with `byte-compile' rather than `byte-compile-file', and + non-top-level forms.) The `eval-when' acts like a `progn' if + `eval' is specified, and like `nil' (ignoring the body FORMS) if + not. + + The rules become more subtle when `eval-when's are nested; consult + Steele (second edition) for the gruesome details (and some + gruesome examples). + + Some simple examples: + + ;; Top-level forms in foo.el: + (eval-when (compile) (setq foo1 'bar)) + (eval-when (load) (setq foo2 'bar)) + (eval-when (compile load) (setq foo3 'bar)) + (eval-when (eval) (setq foo4 'bar)) + (eval-when (eval compile) (setq foo5 'bar)) + (eval-when (eval load) (setq foo6 'bar)) + (eval-when (eval compile load) (setq foo7 'bar)) + + When `foo.el' is compiled, these variables will be set during the + compilation itself: + + foo1 foo3 foo5 foo7 ; `compile' + + When `foo.elc' is loaded, these variables will be set: + + foo2 foo3 foo6 foo7 ; `load' + + And if `foo.el' is loaded uncompiled, these variables will be set: + + foo4 foo5 foo6 foo7 ; `eval' + + If these seven `eval-when's had been, say, inside a `defun', then + the first three would have been equivalent to `nil' and the last + four would have been equivalent to the corresponding `setq's. + + Note that `(eval-when (load eval) ...)' is equivalent to `(progn + ...)' in all contexts. The compiler treats certain top-level + forms, like `defmacro' (sort-of) and `require', as if they were + wrapped in `(eval-when (compile load eval) ...)'. + + Emacs 19 includes two special forms related to `eval-when'. One of +these, `eval-when-compile', is not quite equivalent to any `eval-when' +construct and is described below. This package defines a version of +`eval-when-compile' for the benefit of Emacs 18 users. + + The other form, `(eval-and-compile ...)', is exactly equivalent to +`(eval-when (compile load eval) ...)' and so is not itself defined by +this package. + + - Special Form: eval-when-compile forms... + The FORMS are evaluated at compile-time; at execution time, this + form acts like a quoted constant of the resulting value. Used at + top-level, `eval-when-compile' is just like `eval-when (compile + eval)'. In other contexts, `eval-when-compile' allows code to be + evaluated once at compile-time for efficiency or other reasons. + + This form is similar to the `#.' syntax of true Common Lisp. + + - Special Form: load-time-value form + The FORM is evaluated at load-time; at execution time, this form + acts like a quoted constant of the resulting value. + + Early Common Lisp had a `#,' syntax that was similar to this, but + ANSI Common Lisp replaced it with `load-time-value' and gave it + more well-defined semantics. + + In a compiled file, `load-time-value' arranges for FORM to be + evaluated when the `.elc' file is loaded and then used as if it + were a quoted constant. In code compiled by `byte-compile' rather + than `byte-compile-file', the effect is identical to + `eval-when-compile'. In uncompiled code, both `eval-when-compile' + and `load-time-value' act exactly like `progn'. + + (defun report () + (insert "This function was executed on: " + (current-time-string) + ", compiled on: " + (eval-when-compile (current-time-string)) + ;; or '#.(current-time-string) in real Common Lisp + ", and loaded on: " + (load-time-value (current-time-string)))) + + Byte-compiled, the above defun will result in the following code + (or its compiled equivalent, of course) in the `.elc' file: + + (setq --temp-- (current-time-string)) + (defun report () + (insert "This function was executed on: " + (current-time-string) + ", compiled on: " + '"Wed Jun 23 18:33:43 1993" + ", and loaded on: " + --temp--)) + + +File: cl.info, Node: Function Aliases, Prev: Time of Evaluation, Up: Program Structure + +Function Aliases +================ + +This section describes a feature from GNU Emacs 19 which this package +makes available in other versions of Emacs. + + - Function: defalias symbol function + This function sets SYMBOL's function cell to FUNCTION. It is + equivalent to `fset', except that in GNU Emacs 19 it also records + the setting in `load-history' so that it can be undone by a later + `unload-feature'. + + In other versions of Emacs, `defalias' is a synonym for `fset'. + + +File: cl.info, Node: Predicates, Next: Control Structure, Prev: Program Structure, Up: Top + +Predicates +********** + +This section describes functions for testing whether various facts are +true or false. + +* Menu: + +* Type Predicates:: `typep', `deftype', and `coerce' +* Equality Predicates:: `eql' and `equalp' + + +File: cl.info, Node: Type Predicates, Next: Equality Predicates, Prev: Predicates, Up: Predicates + +Type Predicates +=============== + +The "CL" package defines a version of the Common Lisp `typep' predicate. + + - Function: typep object type + Check if OBJECT is of type TYPE, where TYPE is a (quoted) type + name of the sort used by Common Lisp. For example, `(typep foo + 'integer)' is equivalent to `(integerp foo)'. + + The TYPE argument to the above function is either a symbol or a list +beginning with a symbol. + + * If the type name is a symbol, Emacs appends `-p' to the symbol + name to form the name of a predicate function for testing the + type. (Built-in predicates whose names end in `p' rather than + `-p' are used when appropriate.) + + * The type symbol `t' stands for the union of all types. `(typep + OBJECT t)' is always true. Likewise, the type symbol `nil' stands + for nothing at all, and `(typep OBJECT nil)' is always false. + + * The type symbol `null' represents the symbol `nil'. Thus `(typep + OBJECT 'null)' is equivalent to `(null OBJECT)'. + + * The type symbol `real' is a synonym for `number', and `fixnum' is + a synonym for `integer'. + + * The type symbols `character' and `string-char' match characters. + In Emacs-19 and XEmacs-19, characters are the same thing as + integers in the range 0-255. In XEmacs-20, where characters are a + first-class data type, this checks for actual characters, and + `(typep 8BIT-INTEGER 'character)' will return `nil'. + + * The type symbol `float' uses the `floatp-safe' predicate defined + by this package rather than `floatp', so it will work correctly + even in Emacs versions without floating-point support. + + * The type list `(integer LOW HIGH)' represents all integers between + LOW and HIGH, inclusive. Either bound may be a list of a single + integer to specify an exclusive limit, or a `*' to specify no + limit. The type `(integer * *)' is thus equivalent to `integer'. + + * Likewise, lists beginning with `float', `real', or `number' + represent numbers of that type falling in a particular range. + + * Lists beginning with `and', `or', and `not' form combinations of + types. For example, `(or integer (float 0 *))' represents all + objects that are integers or non-negative floats. + + * Lists beginning with `member' or `member*' represent objects `eql' + to any of the following values. For example, `(member 1 2 3 4)' + is equivalent to `(integer 1 4)', and `(member nil)' is equivalent + to `null'. + + * Lists of the form `(satisfies PREDICATE)' represent all objects + for which PREDICATE returns true when called with that object as + an argument. + + The following function and macro (not technically predicates) are +related to `typep'. + + - Function: coerce object type + This function attempts to convert OBJECT to the specified TYPE. + If OBJECT is already of that type as determined by `typep', it is + simply returned. Otherwise, certain types of conversions will be + made: If TYPE is any sequence type (`string', `list', etc.) then + OBJECT will be converted to that type if possible. If TYPE is + `character', then strings of length one and symbols with + one-character names can be coerced. If TYPE is `float', then + integers can be coerced in versions of Emacs that support floats. + In all other circumstances, `coerce' signals an error. + + - Special Form: deftype name arglist forms... + This macro defines a new type called NAME. It is similar to + `defmacro' in many ways; when NAME is encountered as a type name, + the body FORMS are evaluated and should return a type specifier + that is equivalent to the type. The ARGLIST is a Common Lisp + argument list of the sort accepted by `defmacro*'. The type + specifier `(NAME ARGS...)' is expanded by calling the expander + with those arguments; the type symbol `NAME' is expanded by + calling the expander with no arguments. The ARGLIST is processed + the same as for `defmacro*' except that optional arguments without + explicit defaults use `*' instead of `nil' as the "default" + default. Some examples: + + (deftype null () '(satisfies null)) ; predefined + (deftype list () '(or null cons)) ; predefined + (deftype unsigned-byte (&optional bits) + (list 'integer 0 (if (eq bits '*) bits (1- (lsh 1 bits))))) + (unsigned-byte 8) == (integer 0 255) + (unsigned-byte) == (integer 0 *) + unsigned-byte == (integer 0 *) + + The last example shows how the Common Lisp `unsigned-byte' type + specifier could be implemented if desired; this package does not + implement `unsigned-byte' by default. + + The `typecase' and `check-type' macros also use type names. *Note +Conditionals::. *Note Assertions::. The `map', `concatenate', and +`merge' functions take type-name arguments to specify the type of +sequence to return. *Note Sequences::. + + +File: cl.info, Node: Equality Predicates, Prev: Type Predicates, Up: Predicates + +Equality Predicates +=================== + +This package defines two Common Lisp predicates, `eql' and `equalp'. + + - Function: eql a b + This function is almost the same as `eq', except that if A and B + are numbers of the same type, it compares them for numeric + equality (as if by `equal' instead of `eq'). This makes a + difference only for versions of Emacs that are compiled with + floating-point support, such as Emacs 19. Emacs floats are + allocated objects just like cons cells, which means that `(eq 3.0 + 3.0)' will not necessarily be true--if the two `3.0's were + allocated separately, the pointers will be different even though + the numbers are the same. But `(eql 3.0 3.0)' will always be true. + + The types of the arguments must match, so `(eql 3 3.0)' is still + false. + + Note that Emacs integers are "direct" rather than allocated, which + basically means `(eq 3 3)' will always be true. Thus `eq' and + `eql' behave differently only if floating-point numbers are + involved, and are indistinguishable on Emacs versions that don't + support floats. + + There is a slight inconsistency with Common Lisp in the treatment + of positive and negative zeros. Some machines, notably those with + IEEE standard arithmetic, represent `+0' and `-0' as distinct + values. Normally this doesn't matter because the standard + specifies that `(= 0.0 -0.0)' should always be true, and this is + indeed what Emacs Lisp and Common Lisp do. But the Common Lisp + standard states that `(eql 0.0 -0.0)' and `(equal 0.0 -0.0)' should + be false on IEEE-like machines; Emacs Lisp does not do this, and in + fact the only known way to distinguish between the two zeros in + Emacs Lisp is to `format' them and check for a minus sign. + + - Function: equalp a b + This function is a more flexible version of `equal'. In + particular, it compares strings and characters case-insensitively, + and it compares numbers without regard to type (so that `(equalp 3 + 3.0)' is true). Vectors and conses are compared recursively. All + other objects are compared as if by `equal'. + + This function differs from Common Lisp `equalp' in several + respects. In keeping with the idea that strings are less + vector-like in Emacs Lisp, this package's `equalp' also will not + compare strings against vectors of integers. + + Also note that the Common Lisp functions `member' and `assoc' use +`eql' to compare elements, whereas Emacs Lisp follows the MacLisp +tradition and uses `equal' for these two functions. In Emacs, use +`member*' and `assoc*' to get functions which use `eql' for comparisons. + + +File: cl.info, Node: Control Structure, Next: Macros, Prev: Predicates, Up: Top + +Control Structure +***************** + +The features described in the following sections implement various +advanced control structures, including the powerful `setf' facility and +a number of looping and conditional constructs. + +* Menu: + +* Assignment:: The `psetq' form +* Generalized Variables:: `setf', `incf', `push', etc. +* Variable Bindings:: `progv', `lexical-let', `flet', `macrolet' +* Conditionals:: `when', `unless', `case', `typecase' +* Blocks and Exits:: `block', `return', `return-from' +* Iteration:: `do', `dotimes', `dolist', `do-symbols' +* Loop Facility:: The Common Lisp `loop' macro +* Multiple Values:: `values', `multiple-value-bind', etc. + + +File: cl.info, Node: Assignment, Next: Generalized Variables, Prev: Control Structure, Up: Control Structure + +Assignment +========== + +The `psetq' form is just like `setq', except that multiple assignments +are done in parallel rather than sequentially. + + - Special Form: psetq [symbol form]... + This special form (actually a macro) is used to assign to several + variables simultaneously. Given only one SYMBOL and FORM, it has + the same effect as `setq'. Given several SYMBOL and FORM pairs, + it evaluates all the FORMs in advance and then stores the + corresponding variables afterwards. + + (setq x 2 y 3) + (setq x (+ x y) y (* x y)) + x + => 5 + y ; `y' was computed after `x' was set. + => 15 + (setq x 2 y 3) + (psetq x (+ x y) y (* x y)) + x + => 5 + y ; `y' was computed before `x' was set. + => 6 + + The simplest use of `psetq' is `(psetq x y y x)', which exchanges + the values of two variables. (The `rotatef' form provides an even + more convenient way to swap two variables; *note Modify Macros::.) + + `psetq' always returns `nil'. + + +File: cl.info, Node: Generalized Variables, Next: Variable Bindings, Prev: Assignment, Up: Control Structure + +Generalized Variables +===================== + +A "generalized variable" or "place form" is one of the many places in +Lisp memory where values can be stored. The simplest place form is a +regular Lisp variable. But the cars and cdrs of lists, elements of +arrays, properties of symbols, and many other locations are also places +where Lisp values are stored. + + The `setf' form is like `setq', except that it accepts arbitrary +place forms on the left side rather than just symbols. For example, +`(setf (car a) b)' sets the car of `a' to `b', doing the same operation +as `(setcar a b)' but without having to remember two separate functions +for setting and accessing every type of place. + + Generalized variables are analogous to "lvalues" in the C language, +where `x = a[i]' gets an element from an array and `a[i] = x' stores an +element using the same notation. Just as certain forms like `a[i]' can +be lvalues in C, there is a set of forms that can be generalized +variables in Lisp. + +* Menu: + +* Basic Setf:: `setf' and place forms +* Modify Macros:: `incf', `push', `rotatef', `letf', `callf', etc. +* Customizing Setf:: `define-modify-macro', `defsetf', `define-setf-method' + + +File: cl.info, Node: Basic Setf, Next: Modify Macros, Prev: Generalized Variables, Up: Generalized Variables + +Basic Setf +---------- + +The `setf' macro is the most basic way to operate on generalized +variables. + + - Special Form: setf [place form]... + This macro evaluates FORM and stores it in PLACE, which must be a + valid generalized variable form. If there are several PLACE and + FORM pairs, the assignments are done sequentially just as with + `setq'. `setf' returns the value of the last FORM. + + The following Lisp forms will work as generalized variables, and + so may legally appear in the PLACE argument of `setf': + + * A symbol naming a variable. In other words, `(setf x y)' is + exactly equivalent to `(setq x y)', and `setq' itself is + strictly speaking redundant now that `setf' exists. Many + programmers continue to prefer `setq' for setting simple + variables, though, purely for stylistic or historical reasons. + The form `(setf x y)' actually expands to `(setq x y)', so + there is no performance penalty for using it in compiled code. + + * A call to any of the following Lisp functions: + + car cdr caar .. cddddr + nth rest first .. tenth + aref elt nthcdr + symbol-function symbol-value symbol-plist + get getf gethash + subseq + + Note that for `nthcdr' and `getf', the list argument of the + function must itself be a valid PLACE form. For example, + `(setf (nthcdr 0 foo) 7)' will set `foo' itself to 7. Note + that `push' and `pop' on an `nthcdr' place can be used to + insert or delete at any position in a list. The use of + `nthcdr' as a PLACE form is an extension to standard Common + Lisp. + + * The following Emacs-specific functions are also `setf'-able. + (Some of these are defined only in Emacs 19 or only in + XEmacs.) + + buffer-file-name marker-position + buffer-modified-p match-data + buffer-name mouse-position + buffer-string overlay-end + buffer-substring overlay-get + current-buffer overlay-start + current-case-table point + current-column point-marker + current-global-map point-max + current-input-mode point-min + current-local-map process-buffer + current-window-configuration process-filter + default-file-modes process-sentinel + default-value read-mouse-position + documentation-property screen-height + extent-data screen-menubar + extent-end-position screen-width + extent-start-position selected-window + face-background selected-screen + face-background-pixmap selected-frame + face-font standard-case-table + face-foreground syntax-table + face-underline-p window-buffer + file-modes window-dedicated-p + frame-height window-display-table + frame-parameters window-height + frame-visible-p window-hscroll + frame-width window-point + get-register window-start + getenv window-width + global-key-binding x-get-cut-buffer + keymap-parent x-get-cutbuffer + local-key-binding x-get-secondary-selection + mark x-get-selection + mark-marker + + Most of these have directly corresponding "set" functions, + like `use-local-map' for `current-local-map', or `goto-char' + for `point'. A few, like `point-min', expand to longer + sequences of code when they are `setf''d (`(narrow-to-region + x (point-max))' in this case). + + * A call of the form `(substring SUBPLACE N [M])', where + SUBPLACE is itself a legal generalized variable whose current + value is a string, and where the value stored is also a + string. The new string is spliced into the specified part of + the destination string. For example: + + (setq a (list "hello" "world")) + => ("hello" "world") + (cadr a) + => "world" + (substring (cadr a) 2 4) + => "rl" + (setf (substring (cadr a) 2 4) "o") + => "o" + (cadr a) + => "wood" + a + => ("hello" "wood") + + The generalized variable `buffer-substring', listed above, + also works in this way by replacing a portion of the current + buffer. + + * A call of the form `(apply 'FUNC ...)' or `(apply (function + FUNC) ...)', where FUNC is a `setf'-able function whose store + function is "suitable" in the sense described in Steele's + book; since none of the standard Emacs place functions are + suitable in this sense, this feature is only interesting when + used with places you define yourself with + `define-setf-method' or the long form of `defsetf'. + + * A macro call, in which case the macro is expanded and `setf' + is applied to the resulting form. + + * Any form for which a `defsetf' or `define-setf-method' has + been made. + + Using any forms other than these in the PLACE argument to `setf' + will signal an error. + + The `setf' macro takes care to evaluate all subforms in the proper + left-to-right order; for example, + + (setf (aref vec (incf i)) i) + + looks like it will evaluate `(incf i)' exactly once, before the + following access to `i'; the `setf' expander will insert temporary + variables as necessary to ensure that it does in fact work this + way no matter what setf-method is defined for `aref'. (In this + case, `aset' would be used and no such steps would be necessary + since `aset' takes its arguments in a convenient order.) + + However, if the PLACE form is a macro which explicitly evaluates + its arguments in an unusual order, this unusual order will be + preserved. Adapting an example from Steele, given + + (defmacro wrong-order (x y) (list 'aref y x)) + + the form `(setf (wrong-order A B) 17)' will evaluate B first, then + A, just as in an actual call to `wrong-order'. + + +File: cl.info, Node: Modify Macros, Next: Customizing Setf, Prev: Basic Setf, Up: Generalized Variables + +Modify Macros +------------- + +This package defines a number of other macros besides `setf' that +operate on generalized variables. Many are interesting and useful even +when the PLACE is just a variable name. + + - Special Form: psetf [place form]... + This macro is to `setf' what `psetq' is to `setq': When several + PLACEs and FORMs are involved, the assignments take place in + parallel rather than sequentially. Specifically, all subforms are + evaluated from left to right, then all the assignments are done + (in an undefined order). + + - Special Form: incf place &optional x + This macro increments the number stored in PLACE by one, or by X + if specified. The incremented value is returned. For example, + `(incf i)' is equivalent to `(setq i (1+ i))', and `(incf (car x) + 2)' is equivalent to `(setcar x (+ (car x) 2))'. + + Once again, care is taken to preserve the "apparent" order of + evaluation. For example, + + (incf (aref vec (incf i))) + + appears to increment `i' once, then increment the element of `vec' + addressed by `i'; this is indeed exactly what it does, which means + the above form is _not_ equivalent to the "obvious" expansion, + + (setf (aref vec (incf i)) (1+ (aref vec (incf i)))) ; Wrong! + + but rather to something more like + + (let ((temp (incf i))) + (setf (aref vec temp) (1+ (aref vec temp)))) + + Again, all of this is taken care of automatically by `incf' and + the other generalized-variable macros. + + As a more Emacs-specific example of `incf', the expression `(incf + (point) N)' is essentially equivalent to `(forward-char N)'. + + - Special Form: decf place &optional x + This macro decrements the number stored in PLACE by one, or by X + if specified. + + - Special Form: pop place + This macro removes and returns the first element of the list stored + in PLACE. It is analogous to `(prog1 (car PLACE) (setf PLACE (cdr + PLACE)))', except that it takes care to evaluate all subforms only + once. + + - Special Form: push x place + This macro inserts X at the front of the list stored in PLACE. It + is analogous to `(setf PLACE (cons X PLACE))', except for + evaluation of the subforms. + + - Special Form: pushnew x place &key :test :test-not :key + This macro inserts X at the front of the list stored in PLACE, but + only if X was not `eql' to any existing element of the list. The + optional keyword arguments are interpreted in the same way as for + `adjoin'. *Note Lists as Sets::. + + - Special Form: shiftf place... newvalue + This macro shifts the PLACEs left by one, shifting in the value of + NEWVALUE (which may be any Lisp expression, not just a generalized + variable), and returning the value shifted out of the first PLACE. + Thus, `(shiftf A B C D)' is equivalent to + + (prog1 + A + (psetf A B + B C + C D)) + + except that the subforms of A, B, and C are actually evaluated + only once each and in the apparent order. + + - Special Form: rotatef place... + This macro rotates the PLACEs left by one in circular fashion. + Thus, `(rotatef A B C D)' is equivalent to + + (psetf A B + B C + C D + D A) + + except for the evaluation of subforms. `rotatef' always returns + `nil'. Note that `(rotatef A B)' conveniently exchanges A and B. + + The following macros were invented for this package; they have no +analogues in Common Lisp. + + - Special Form: letf (bindings...) forms... + This macro is analogous to `let', but for generalized variables + rather than just symbols. Each BINDING should be of the form + `(PLACE VALUE)'; the original contents of the PLACEs are saved, + the VALUEs are stored in them, and then the body FORMs are + executed. Afterwards, the PLACES are set back to their original + saved contents. This cleanup happens even if the FORMs exit + irregularly due to a `throw' or an error. + + For example, + + (letf (((point) (point-min)) + (a 17)) + ...) + + moves "point" in the current buffer to the beginning of the buffer, + and also binds `a' to 17 (as if by a normal `let', since `a' is + just a regular variable). After the body exits, `a' is set back + to its original value and point is moved back to its original + position. + + Note that `letf' on `(point)' is not quite like a + `save-excursion', as the latter effectively saves a marker which + tracks insertions and deletions in the buffer. Actually, a `letf' + of `(point-marker)' is much closer to this behavior. (`point' and + `point-marker' are equivalent as `setf' places; each will accept + either an integer or a marker as the stored value.) + + Since generalized variables look like lists, `let''s shorthand of + using `foo' for `(foo nil)' as a BINDING would be ambiguous in + `letf' and is not allowed. + + However, a BINDING specifier may be a one-element list `(PLACE)', + which is similar to `(PLACE PLACE)'. In other words, the PLACE is + not disturbed on entry to the body, and the only effect of the + `letf' is to restore the original value of PLACE afterwards. (The + redundant access-and-store suggested by the `(PLACE PLACE)' + example does not actually occur.) + + In most cases, the PLACE must have a well-defined value on entry + to the `letf' form. The only exceptions are plain variables and + calls to `symbol-value' and `symbol-function'. If the symbol is + not bound on entry, it is simply made unbound by `makunbound' or + `fmakunbound' on exit. + + - Special Form: letf* (bindings...) forms... + This macro is to `letf' what `let*' is to `let': It does the + bindings in sequential rather than parallel order. + + - Special Form: callf FUNCTION PLACE ARGS... + This is the "generic" modify macro. It calls FUNCTION, which + should be an unquoted function name, macro name, or lambda. It + passes PLACE and ARGS as arguments, and assigns the result back to + PLACE. For example, `(incf PLACE N)' is the same as `(callf + + PLACE N)'. Some more examples: + + (callf abs my-number) + (callf concat (buffer-name) "<" (int-to-string n) ">") + (callf union happy-people (list joe bob) :test 'same-person) + + *Note Customizing Setf::, for `define-modify-macro', a way to + create even more concise notations for modify macros. Note again + that `callf' is an extension to standard Common Lisp. + + - Special Form: callf2 FUNCTION ARG1 PLACE ARGS... + This macro is like `callf', except that PLACE is the _second_ + argument of FUNCTION rather than the first. For example, `(push X + PLACE)' is equivalent to `(callf2 cons X PLACE)'. + + The `callf' and `callf2' macros serve as building blocks for other +macros like `incf', `pushnew', and `define-modify-macro'. The `letf' +and `letf*' macros are used in the processing of symbol macros; *note +Macro Bindings::. + + +File: cl.info, Node: Customizing Setf, Prev: Modify Macros, Up: Generalized Variables + +Customizing Setf +---------------- + +Common Lisp defines three macros, `define-modify-macro', `defsetf', and +`define-setf-method', that allow the user to extend generalized +variables in various ways. + + - Special Form: define-modify-macro name arglist function [doc-string] + This macro defines a "read-modify-write" macro similar to `incf' + and `decf'. The macro NAME is defined to take a PLACE argument + followed by additional arguments described by ARGLIST. The call + + (NAME PLACE ARGS...) + + will be expanded to + + (callf FUNC PLACE ARGS...) + + which in turn is roughly equivalent to + + (setf PLACE (FUNC PLACE ARGS...)) + + For example: + + (define-modify-macro incf (&optional (n 1)) +) + (define-modify-macro concatf (&rest args) concat) + + Note that `&key' is not allowed in ARGLIST, but `&rest' is + sufficient to pass keywords on to the function. + + Most of the modify macros defined by Common Lisp do not exactly + follow the pattern of `define-modify-macro'. For example, `push' + takes its arguments in the wrong order, and `pop' is completely + irregular. You can define these macros "by hand" using + `get-setf-method', or consult the source file `cl-macs.el' to see + how to use the internal `setf' building blocks. + + - Special Form: defsetf access-fn update-fn + This is the simpler of two `defsetf' forms. Where ACCESS-FN is + the name of a function which accesses a place, this declares + UPDATE-FN to be the corresponding store function. From now on, + + (setf (ACCESS-FN ARG1 ARG2 ARG3) VALUE) + + will be expanded to + + (UPDATE-FN ARG1 ARG2 ARG3 VALUE) + + The UPDATE-FN is required to be either a true function, or a macro + which evaluates its arguments in a function-like way. Also, the + UPDATE-FN is expected to return VALUE as its result. Otherwise, + the above expansion would not obey the rules for the way `setf' is + supposed to behave. + + As a special (non-Common-Lisp) extension, a third argument of `t' + to `defsetf' says that the `update-fn''s return value is not + suitable, so that the above `setf' should be expanded to something + more like + + (let ((temp VALUE)) + (UPDATE-FN ARG1 ARG2 ARG3 temp) + temp) + + Some examples of the use of `defsetf', drawn from the standard + suite of setf methods, are: + + (defsetf car setcar) + (defsetf symbol-value set) + (defsetf buffer-name rename-buffer t) + + - Special Form: defsetf access-fn arglist (store-var) forms... + This is the second, more complex, form of `defsetf'. It is rather + like `defmacro' except for the additional STORE-VAR argument. The + FORMS should return a Lisp form which stores the value of + STORE-VAR into the generalized variable formed by a call to + ACCESS-FN with arguments described by ARGLIST. The FORMS may + begin with a string which documents the `setf' method (analogous + to the doc string that appears at the front of a function). + + For example, the simple form of `defsetf' is shorthand for + + (defsetf ACCESS-FN (&rest args) (store) + (append '(UPDATE-FN) args (list store))) + + The Lisp form that is returned can access the arguments from + ARGLIST and STORE-VAR in an unrestricted fashion; macros like + `setf' and `incf' which invoke this setf-method will insert + temporary variables as needed to make sure the apparent order of + evaluation is preserved. + + Another example drawn from the standard package: + + (defsetf nth (n x) (store) + (list 'setcar (list 'nthcdr n x) store)) + + - Special Form: define-setf-method access-fn arglist forms... + This is the most general way to create new place forms. When a + `setf' to ACCESS-FN with arguments described by ARGLIST is + expanded, the FORMS are evaluated and must return a list of five + items: + + 1. A list of "temporary variables". + + 2. A list of "value forms" corresponding to the temporary + variables above. The temporary variables will be bound to + these value forms as the first step of any operation on the + generalized variable. + + 3. A list of exactly one "store variable" (generally obtained + from a call to `gensym'). + + 4. A Lisp form which stores the contents of the store variable + into the generalized variable, assuming the temporaries have + been bound as described above. + + 5. A Lisp form which accesses the contents of the generalized + variable, assuming the temporaries have been bound. + + This is exactly like the Common Lisp macro of the same name, + except that the method returns a list of five values rather than + the five values themselves, since Emacs Lisp does not support + Common Lisp's notion of multiple return values. + + Once again, the FORMS may begin with a documentation string. + + A setf-method should be maximally conservative with regard to + temporary variables. In the setf-methods generated by `defsetf', + the second return value is simply the list of arguments in the + place form, and the first return value is a list of a + corresponding number of temporary variables generated by `gensym'. + Macros like `setf' and `incf' which use this setf-method will + optimize away most temporaries that turn out to be unnecessary, so + there is little reason for the setf-method itself to optimize. + + - Function: get-setf-method place &optional env + This function returns the setf-method for PLACE, by invoking the + definition previously recorded by `defsetf' or + `define-setf-method'. The result is a list of five values as + described above. You can use this function to build your own + `incf'-like modify macros. (Actually, it is better to use the + internal functions `cl-setf-do-modify' and `cl-setf-do-store', + which are a bit easier to use and which also do a number of + optimizations; consult the source code for the `incf' function for + a simple example.) + + The argument ENV specifies the "environment" to be passed on to + `macroexpand' if `get-setf-method' should need to expand a macro + in PLACE. It should come from an `&environment' argument to the + macro or setf-method that called `get-setf-method'. + + See also the source code for the setf-methods for `apply' and + `substring', each of which works by calling `get-setf-method' on a + simpler case, then massaging the result in various ways. + + Modern Common Lisp defines a second, independent way to specify the +`setf' behavior of a function, namely "`setf' functions" whose names +are lists `(setf NAME)' rather than symbols. For example, `(defun +(setf foo) ...)' defines the function that is used when `setf' is +applied to `foo'. This package does not currently support `setf' +functions. In particular, it is a compile-time error to use `setf' on +a form which has not already been `defsetf''d or otherwise declared; in +newer Common Lisps, this would not be an error since the function +`(setf FUNC)' might be defined later. + + +File: cl.info, Node: Variable Bindings, Next: Conditionals, Prev: Generalized Variables, Up: Control Structure + +Variable Bindings +================= + +These Lisp forms make bindings to variables and function names, +analogous to Lisp's built-in `let' form. + + *Note Modify Macros::, for the `letf' and `letf*' forms which are +also related to variable bindings. + +* Menu: + +* Dynamic Bindings:: The `progv' form +* Lexical Bindings:: `lexical-let' and lexical closures +* Function Bindings:: `flet' and `labels' +* Macro Bindings:: `macrolet' and `symbol-macrolet' + + +File: cl.info, Node: Dynamic Bindings, Next: Lexical Bindings, Prev: Variable Bindings, Up: Variable Bindings + +Dynamic Bindings +---------------- + +The standard `let' form binds variables whose names are known at +compile-time. The `progv' form provides an easy way to bind variables +whose names are computed at run-time. + + - Special Form: progv symbols values forms... + This form establishes `let'-style variable bindings on a set of + variables computed at run-time. The expressions SYMBOLS and + VALUES are evaluated, and must return lists of symbols and values, + respectively. The symbols are bound to the corresponding values + for the duration of the body FORMs. If VALUES is shorter than + SYMBOLS, the last few symbols are made unbound (as if by + `makunbound') inside the body. If SYMBOLS is shorter than VALUES, + the excess values are ignored. + + +File: cl.info, Node: Lexical Bindings, Next: Function Bindings, Prev: Dynamic Bindings, Up: Variable Bindings + +Lexical Bindings +---------------- + +The "CL" package defines the following macro which more closely follows +the Common Lisp `let' form: + + - Special Form: lexical-let (bindings...) forms... + This form is exactly like `let' except that the bindings it + establishes are purely lexical. Lexical bindings are similar to + local variables in a language like C: Only the code physically + within the body of the `lexical-let' (after macro expansion) may + refer to the bound variables. + + (setq a 5) + (defun foo (b) (+ a b)) + (let ((a 2)) (foo a)) + => 4 + (lexical-let ((a 2)) (foo a)) + => 7 + + In this example, a regular `let' binding of `a' actually makes a + temporary change to the global variable `a', so `foo' is able to + see the binding of `a' to 2. But `lexical-let' actually creates a + distinct local variable `a' for use within its body, without any + effect on the global variable of the same name. + + The most important use of lexical bindings is to create "closures". + A closure is a function object that refers to an outside lexical + variable. For example: + + (defun make-adder (n) + (lexical-let ((n n)) + (function (lambda (m) (+ n m))))) + (setq add17 (make-adder 17)) + (funcall add17 4) + => 21 + + The call `(make-adder 17)' returns a function object which adds 17 + to its argument. If `let' had been used instead of `lexical-let', + the function object would have referred to the global `n', which + would have been bound to 17 only during the call to `make-adder' + itself. + + (defun make-counter () + (lexical-let ((n 0)) + (function* (lambda (&optional (m 1)) (incf n m))))) + (setq count-1 (make-counter)) + (funcall count-1 3) + => 3 + (funcall count-1 14) + => 17 + (setq count-2 (make-counter)) + (funcall count-2 5) + => 5 + (funcall count-1 2) + => 19 + (funcall count-2) + => 6 + + Here we see that each call to `make-counter' creates a distinct + local variable `n', which serves as a private counter for the + function object that is returned. + + Closed-over lexical variables persist until the last reference to + them goes away, just like all other Lisp objects. For example, + `count-2' refers to a function object which refers to an instance + of the variable `n'; this is the only reference to that variable, + so after `(setq count-2 nil)' the garbage collector would be able + to delete this instance of `n'. Of course, if a `lexical-let' + does not actually create any closures, then the lexical variables + are free as soon as the `lexical-let' returns. + + Many closures are used only during the extent of the bindings they + refer to; these are known as "downward funargs" in Lisp parlance. + When a closure is used in this way, regular Emacs Lisp dynamic + bindings suffice and will be more efficient than `lexical-let' + closures: + + (defun add-to-list (x list) + (mapcar (function (lambda (y) (+ x y))) list)) + (add-to-list 7 '(1 2 5)) + => (8 9 12) + + Since this lambda is only used while `x' is still bound, it is not + necessary to make a true closure out of it. + + You can use `defun' or `flet' inside a `lexical-let' to create a + named closure. If several closures are created in the body of a + single `lexical-let', they all close over the same instance of the + lexical variable. + + The `lexical-let' form is an extension to Common Lisp. In true + Common Lisp, all bindings are lexical unless declared otherwise. + + - Special Form: lexical-let* (bindings...) forms... + This form is just like `lexical-let', except that the bindings are + made sequentially in the manner of `let*'. + + +File: cl.info, Node: Function Bindings, Next: Macro Bindings, Prev: Lexical Bindings, Up: Variable Bindings + +Function Bindings +----------------- + +These forms make `let'-like bindings to functions instead of variables. + + - Special Form: flet (bindings...) forms... + This form establishes `let'-style bindings on the function cells + of symbols rather than on the value cells. Each BINDING must be a + list of the form `(NAME ARGLIST FORMS...)', which defines a + function exactly as if it were a `defun*' form. The function NAME + is defined accordingly for the duration of the body of the `flet'; + then the old function definition, or lack thereof, is restored. + + While `flet' in Common Lisp establishes a lexical binding of NAME, + Emacs Lisp `flet' makes a dynamic binding. The result is that + `flet' affects indirect calls to a function as well as calls + directly inside the `flet' form itself. + + You can use `flet' to disable or modify the behavior of a function + in a temporary fashion. This will even work on Emacs primitives, + although note that some calls to primitive functions internal to + Emacs are made without going through the symbol's function cell, + and so will not be affected by `flet'. For example, + + (flet ((message (&rest args) (push args saved-msgs))) + (do-something)) + + This code attempts to replace the built-in function `message' with + a function that simply saves the messages in a list rather than + displaying them. The original definition of `message' will be + restored after `do-something' exits. This code will work fine on + messages generated by other Lisp code, but messages generated + directly inside Emacs will not be caught since they make direct + C-language calls to the message routines rather than going through + the Lisp `message' function. + + Functions defined by `flet' may use the full Common Lisp argument + notation supported by `defun*'; also, the function body is + enclosed in an implicit block as if by `defun*'. *Note Program + Structure::. + + - Special Form: labels (bindings...) forms... + The `labels' form is a synonym for `flet'. (In Common Lisp, + `labels' and `flet' differ in ways that depend on their lexical + scoping; these distinctions vanish in dynamically scoped Emacs + Lisp.) + + +File: cl.info, Node: Macro Bindings, Prev: Function Bindings, Up: Variable Bindings + +Macro Bindings +-------------- + +These forms create local macros and "symbol macros." + + - Special Form: macrolet (bindings...) forms... + This form is analogous to `flet', but for macros instead of + functions. Each BINDING is a list of the same form as the + arguments to `defmacro*' (i.e., a macro name, argument list, and + macro-expander forms). The macro is defined accordingly for use + within the body of the `macrolet'. + + Because of the nature of macros, `macrolet' is lexically scoped + even in Emacs Lisp: The `macrolet' binding will affect only calls + that appear physically within the body FORMS, possibly after + expansion of other macros in the body. + + - Special Form: symbol-macrolet (bindings...) forms... + This form creates "symbol macros", which are macros that look like + variable references rather than function calls. Each BINDING is a + list `(VAR EXPANSION)'; any reference to VAR within the body FORMS + is replaced by EXPANSION. + + (setq bar '(5 . 9)) + (symbol-macrolet ((foo (car bar))) + (incf foo)) + bar + => (6 . 9) + + A `setq' of a symbol macro is treated the same as a `setf'. I.e., + `(setq foo 4)' in the above would be equivalent to `(setf foo 4)', + which in turn expands to `(setf (car bar) 4)'. + + Likewise, a `let' or `let*' binding a symbol macro is treated like + a `letf' or `letf*'. This differs from true Common Lisp, where + the rules of lexical scoping cause a `let' binding to shadow a + `symbol-macrolet' binding. In this package, only `lexical-let' + and `lexical-let*' will shadow a symbol macro. + + There is no analogue of `defmacro' for symbol macros; all symbol + macros are local. A typical use of `symbol-macrolet' is in the + expansion of another macro: + + (defmacro* my-dolist ((x list) &rest body) + (let ((var (gensym))) + (list 'loop 'for var 'on list 'do + (list* 'symbol-macrolet (list (list x (list 'car var))) + body)))) + + (setq mylist '(1 2 3 4)) + (my-dolist (x mylist) (incf x)) + mylist + => (2 3 4 5) + + In this example, the `my-dolist' macro is similar to `dolist' + (*note Iteration::) except that the variable `x' becomes a true + reference onto the elements of the list. The `my-dolist' call + shown here expands to + + (loop for G1234 on mylist do + (symbol-macrolet ((x (car G1234))) + (incf x))) + + which in turn expands to + + (loop for G1234 on mylist do (incf (car G1234))) + + *Note Loop Facility::, for a description of the `loop' macro. + This package defines a nonstandard `in-ref' loop clause that works + much like `my-dolist'. + + +File: cl.info, Node: Conditionals, Next: Blocks and Exits, Prev: Variable Bindings, Up: Control Structure + +Conditionals +============ + +These conditional forms augment Emacs Lisp's simple `if', `and', `or', +and `cond' forms. + + - Special Form: when test forms... + This is a variant of `if' where there are no "else" forms, and + possibly several "then" forms. In particular, + + (when TEST A B C) + + is entirely equivalent to + + (if TEST (progn A B C) nil) + + - Special Form: unless test forms... + This is a variant of `if' where there are no "then" forms, and + possibly several "else" forms: + + (unless TEST A B C) + + is entirely equivalent to + + (when (not TEST) A B C) + + - Special Form: case keyform clause... + This macro evaluates KEYFORM, then compares it with the key values + listed in the various CLAUSEs. Whichever clause matches the key + is executed; comparison is done by `eql'. If no clause matches, + the `case' form returns `nil'. The clauses are of the form + + (KEYLIST BODY-FORMS...) + + where KEYLIST is a list of key values. If there is exactly one + value, and it is not a cons cell or the symbol `nil' or `t', then + it can be used by itself as a KEYLIST without being enclosed in a + list. All key values in the `case' form must be distinct. The + final clauses may use `t' in place of a KEYLIST to indicate a + default clause that should be taken if none of the other clauses + match. (The symbol `otherwise' is also recognized in place of + `t'. To make a clause that matches the actual symbol `t', `nil', + or `otherwise', enclose the symbol in a list.) + + For example, this expression reads a keystroke, then does one of + four things depending on whether it is an `a', a `b', a or + , or anything else. + + (case (read-char) + (?a (do-a-thing)) + (?b (do-b-thing)) + ((?\r ?\n) (do-ret-thing)) + (t (do-other-thing))) + + - Special Form: ecase keyform clause... + This macro is just like `case', except that if the key does not + match any of the clauses, an error is signalled rather than simply + returning `nil'. + + - Special Form: typecase keyform clause... + This macro is a version of `case' that checks for types rather + than values. Each CLAUSE is of the form `(TYPE BODY...)'. *Note + Type Predicates::, for a description of type specifiers. For + example, + + (typecase x + (integer (munch-integer x)) + (float (munch-float x)) + (string (munch-integer (string-to-int x))) + (t (munch-anything x))) + + The type specifier `t' matches any type of object; the word + `otherwise' is also allowed. To make one clause match any of + several types, use an `(or ...)' type specifier. + + - Special Form: etypecase keyform clause... + This macro is just like `typecase', except that if the key does + not match any of the clauses, an error is signalled rather than + simply returning `nil'. + + +File: cl.info, Node: Blocks and Exits, Next: Iteration, Prev: Conditionals, Up: Control Structure + +Blocks and Exits +================ + +Common Lisp "blocks" provide a non-local exit mechanism very similar to +`catch' and `throw', but lexically rather than dynamically scoped. +This package actually implements `block' in terms of `catch'; however, +the lexical scoping allows the optimizing byte-compiler to omit the +costly `catch' step if the body of the block does not actually +`return-from' the block. + + - Special Form: block name forms... + The FORMS are evaluated as if by a `progn'. However, if any of + the FORMS execute `(return-from NAME)', they will jump out and + return directly from the `block' form. The `block' returns the + result of the last FORM unless a `return-from' occurs. + + The `block'/`return-from' mechanism is quite similar to the + `catch'/`throw' mechanism. The main differences are that block + NAMEs are unevaluated symbols, rather than forms (such as quoted + symbols) which evaluate to a tag at run-time; and also that blocks + are lexically scoped whereas `catch'/`throw' are dynamically + scoped. This means that functions called from the body of a + `catch' can also `throw' to the `catch', but the `return-from' + referring to a block name must appear physically within the FORMS + that make up the body of the block. They may not appear within + other called functions, although they may appear within macro + expansions or `lambda's in the body. Block names and `catch' + names form independent name-spaces. + + In true Common Lisp, `defun' and `defmacro' surround the function + or expander bodies with implicit blocks with the same name as the + function or macro. This does not occur in Emacs Lisp, but this + package provides `defun*' and `defmacro*' forms which do create + the implicit block. + + The Common Lisp looping constructs defined by this package, such + as `loop' and `dolist', also create implicit blocks just as in + Common Lisp. + + Because they are implemented in terms of Emacs Lisp `catch' and + `throw', blocks have the same overhead as actual `catch' + constructs (roughly two function calls). However, Zawinski and + Furuseth's optimizing byte compiler (standard in Emacs 19) will + optimize away the `catch' if the block does not in fact contain + any `return' or `return-from' calls that jump to it. This means + that `do' loops and `defun*' functions which don't use `return' + don't pay the overhead to support it. + + - Special Form: return-from name [result] + This macro returns from the block named NAME, which must be an + (unevaluated) symbol. If a RESULT form is specified, it is + evaluated to produce the result returned from the `block'. + Otherwise, `nil' is returned. + + - Special Form: return [result] + This macro is exactly like `(return-from nil RESULT)'. Common + Lisp loops like `do' and `dolist' implicitly enclose themselves in + `nil' blocks. + + +File: cl.info, Node: Iteration, Next: Loop Facility, Prev: Blocks and Exits, Up: Control Structure + +Iteration +========= + +The macros described here provide more sophisticated, high-level +looping constructs to complement Emacs Lisp's basic `while' loop. + + - Special Form: loop forms... + The "CL" package supports both the simple, old-style meaning of + `loop' and the extremely powerful and flexible feature known as + the "Loop Facility" or "Loop Macro". This more advanced facility + is discussed in the following section; *note Loop Facility::. The + simple form of `loop' is described here. + + If `loop' is followed by zero or more Lisp expressions, then + `(loop EXPRS...)' simply creates an infinite loop executing the + expressions over and over. The loop is enclosed in an implicit + `nil' block. Thus, + + (loop (foo) (if (no-more) (return 72)) (bar)) + + is exactly equivalent to + + (block nil (while t (foo) (if (no-more) (return 72)) (bar))) + + If any of the expressions are plain symbols, the loop is instead + interpreted as a Loop Macro specification as described later. + (This is not a restriction in practice, since a plain symbol in + the above notation would simply access and throw away the value of + a variable.) + + - Special Form: do (spec...) (end-test [result...]) forms... + This macro creates a general iterative loop. Each SPEC is of the + form + + (VAR [INIT [STEP]]) + + The loop works as follows: First, each VAR is bound to the + associated INIT value as if by a `let' form. Then, in each + iteration of the loop, the END-TEST is evaluated; if true, the + loop is finished. Otherwise, the body FORMS are evaluated, then + each VAR is set to the associated STEP expression (as if by a + `psetq' form) and the next iteration begins. Once the END-TEST + becomes true, the RESULT forms are evaluated (with the VARs still + bound to their values) to produce the result returned by `do'. + + The entire `do' loop is enclosed in an implicit `nil' block, so + that you can use `(return)' to break out of the loop at any time. + + If there are no RESULT forms, the loop returns `nil'. If a given + VAR has no STEP form, it is bound to its INIT value but not + otherwise modified during the `do' loop (unless the code + explicitly modifies it); this case is just a shorthand for putting + a `(let ((VAR INIT)) ...)' around the loop. If INIT is also + omitted it defaults to `nil', and in this case a plain `VAR' can + be used in place of `(VAR)', again following the analogy with + `let'. + + This example (from Steele) illustrates a loop which applies the + function `f' to successive pairs of values from the lists `foo' + and `bar'; it is equivalent to the call `(mapcar* 'f foo bar)'. + Note that this loop has no body FORMS at all, performing all its + work as side effects of the rest of the loop. + + (do ((x foo (cdr x)) + (y bar (cdr y)) + (z nil (cons (f (car x) (car y)) z))) + ((or (null x) (null y)) + (nreverse z))) + + - Special Form: do* (spec...) (end-test [result...]) forms... + This is to `do' what `let*' is to `let'. In particular, the + initial values are bound as if by `let*' rather than `let', and + the steps are assigned as if by `setq' rather than `psetq'. + + Here is another way to write the above loop: + + (do* ((xp foo (cdr xp)) + (yp bar (cdr yp)) + (x (car xp) (car xp)) + (y (car yp) (car yp)) + z) + ((or (null xp) (null yp)) + (nreverse z)) + (push (f x y) z)) + + - Special Form: dolist (var list [result]) forms... + This is a more specialized loop which iterates across the elements + of a list. LIST should evaluate to a list; the body FORMS are + executed with VAR bound to each element of the list in turn. + Finally, the RESULT form (or `nil') is evaluated with VAR bound to + `nil' to produce the result returned by the loop. The loop is + surrounded by an implicit `nil' block. + + - Special Form: dotimes (var count [result]) forms... + This is a more specialized loop which iterates a specified number + of times. The body is executed with VAR bound to the integers + from zero (inclusive) to COUNT (exclusive), in turn. Then the + `result' form is evaluated with VAR bound to the total number of + iterations that were done (i.e., `(max 0 COUNT)') to get the + return value for the loop form. The loop is surrounded by an + implicit `nil' block. + + - Special Form: do-symbols (var [obarray [result]]) forms... + This loop iterates over all interned symbols. If OBARRAY is + specified and is not `nil', it loops over all symbols in that + obarray. For each symbol, the body FORMS are evaluated with VAR + bound to that symbol. The symbols are visited in an unspecified + order. Afterward the RESULT form, if any, is evaluated (with VAR + bound to `nil') to get the return value. The loop is surrounded + by an implicit `nil' block. + + - Special Form: do-all-symbols (var [result]) forms... + This is identical to `do-symbols' except that the OBARRAY argument + is omitted; it always iterates over the default obarray. + + *Note Mapping over Sequences::, for some more functions for +iterating over vectors or lists. + + +File: cl.info, Node: Loop Facility, Next: Multiple Values, Prev: Iteration, Up: Control Structure + +Loop Facility +============= + +A common complaint with Lisp's traditional looping constructs is that +they are either too simple and limited, such as Common Lisp's `dotimes' +or Emacs Lisp's `while', or too unreadable and obscure, like Common +Lisp's `do' loop. + + To remedy this, recent versions of Common Lisp have added a new +construct called the "Loop Facility" or "`loop' macro," with an +easy-to-use but very powerful and expressive syntax. + +* Menu: + +* Loop Basics:: `loop' macro, basic clause structure +* Loop Examples:: Working examples of `loop' macro +* For Clauses:: Clauses introduced by `for' or `as' +* Iteration Clauses:: `repeat', `while', `thereis', etc. +* Accumulation Clauses:: `collect', `sum', `maximize', etc. +* Other Clauses:: `with', `if', `initially', `finally' + + +File: cl.info, Node: Loop Basics, Next: Loop Examples, Prev: Loop Facility, Up: Loop Facility + +Loop Basics +----------- + +The `loop' macro essentially creates a mini-language within Lisp that +is specially tailored for describing loops. While this language is a +little strange-looking by the standards of regular Lisp, it turns out +to be very easy to learn and well-suited to its purpose. + + Since `loop' is a macro, all parsing of the loop language takes +place at byte-compile time; compiled `loop's are just as efficient as +the equivalent `while' loops written longhand. + + - Special Form: loop clauses... + A loop construct consists of a series of CLAUSEs, each introduced + by a symbol like `for' or `do'. Clauses are simply strung + together in the argument list of `loop', with minimal extra + parentheses. The various types of clauses specify + initializations, such as the binding of temporary variables, + actions to be taken in the loop, stepping actions, and final + cleanup. + + Common Lisp specifies a certain general order of clauses in a loop: + + (loop NAME-CLAUSE + VAR-CLAUSES... + ACTION-CLAUSES...) + + The NAME-CLAUSE optionally gives a name to the implicit block that + surrounds the loop. By default, the implicit block is named + `nil'. The VAR-CLAUSES specify what variables should be bound + during the loop, and how they should be modified or iterated + throughout the course of the loop. The ACTION-CLAUSES are things + to be done during the loop, such as computing, collecting, and + returning values. + + The Emacs version of the `loop' macro is less restrictive about + the order of clauses, but things will behave most predictably if + you put the variable-binding clauses `with', `for', and `repeat' + before the action clauses. As in Common Lisp, `initially' and + `finally' clauses can go anywhere. + + Loops generally return `nil' by default, but you can cause them to + return a value by using an accumulation clause like `collect', an + end-test clause like `always', or an explicit `return' clause to + jump out of the implicit block. (Because the loop body is + enclosed in an implicit block, you can also use regular Lisp + `return' or `return-from' to break out of the loop.) + + The following sections give some examples of the Loop Macro in +action, and describe the particular loop clauses in great detail. +Consult the second edition of Steele's "Common Lisp, the Language", for +additional discussion and examples of the `loop' macro. + + +File: cl.info, Node: Loop Examples, Next: For Clauses, Prev: Loop Basics, Up: Loop Facility + +Loop Examples +------------- + +Before listing the full set of clauses that are allowed, let's look at +a few example loops just to get a feel for the `loop' language. + + (loop for buf in (buffer-list) + collect (buffer-file-name buf)) + +This loop iterates over all Emacs buffers, using the list returned by +`buffer-list'. For each buffer `buf', it calls `buffer-file-name' and +collects the results into a list, which is then returned from the +`loop' construct. The result is a list of the file names of all the +buffers in Emacs' memory. The words `for', `in', and `collect' are +reserved words in the `loop' language. + + (loop repeat 20 do (insert "Yowsa\n")) + +This loop inserts the phrase "Yowsa" twenty times in the current buffer. + + (loop until (eobp) do (munch-line) (forward-line 1)) + +This loop calls `munch-line' on every line until the end of the buffer. +If point is already at the end of the buffer, the loop exits +immediately. + + (loop do (munch-line) until (eobp) do (forward-line 1)) + +This loop is similar to the above one, except that `munch-line' is +always called at least once. + + (loop for x from 1 to 100 + for y = (* x x) + until (>= y 729) + finally return (list x (= y 729))) + +This more complicated loop searches for a number `x' whose square is +729. For safety's sake it only examines `x' values up to 100; dropping +the phrase `to 100' would cause the loop to count upwards with no +limit. The second `for' clause defines `y' to be the square of `x' +within the loop; the expression after the `=' sign is reevaluated each +time through the loop. The `until' clause gives a condition for +terminating the loop, and the `finally' clause says what to do when the +loop finishes. (This particular example was written less concisely +than it could have been, just for the sake of illustration.) + + Note that even though this loop contains three clauses (two `for's +and an `until') that would have been enough to define loops all by +themselves, it still creates a single loop rather than some sort of +triple-nested loop. You must explicitly nest your `loop' constructs if +you want nested loops. + + +File: cl.info, Node: For Clauses, Next: Iteration Clauses, Prev: Loop Examples, Up: Loop Facility + +For Clauses +----------- + +Most loops are governed by one or more `for' clauses. A `for' clause +simultaneously describes variables to be bound, how those variables are +to be stepped during the loop, and usually an end condition based on +those variables. + + The word `as' is a synonym for the word `for'. This word is +followed by a variable name, then a word like `from' or `across' that +describes the kind of iteration desired. In Common Lisp, the phrase +`being the' sometimes precedes the type of iteration; in this package +both `being' and `the' are optional. The word `each' is a synonym for +`the', and the word that follows it may be singular or plural: `for x +being the elements of y' or `for x being each element of y'. Which +form you use is purely a matter of style. + + The variable is bound around the loop as if by `let': + + (setq i 'happy) + (loop for i from 1 to 10 do (do-something-with i)) + i + => happy + +`for VAR from EXPR1 to EXPR2 by EXPR3' + This type of `for' clause creates a counting loop. Each of the + three sub-terms is optional, though there must be at least one + term so that the clause is marked as a counting clause. + + The three expressions are the starting value, the ending value, and + the step value, respectively, of the variable. The loop counts + upwards by default (EXPR3 must be positive), from EXPR1 to EXPR2 + inclusively. If you omit the `from' term, the loop counts from + zero; if you omit the `to' term, the loop counts forever without + stopping (unless stopped by some other loop clause, of course); if + you omit the `by' term, the loop counts in steps of one. + + You can replace the word `from' with `upfrom' or `downfrom' to + indicate the direction of the loop. Likewise, you can replace + `to' with `upto' or `downto'. For example, `for x from 5 downto + 1' executes five times with `x' taking on the integers from 5 down + to 1 in turn. Also, you can replace `to' with `below' or `above', + which are like `upto' and `downto' respectively except that they + are exclusive rather than inclusive limits: + + (loop for x to 10 collect x) + => (0 1 2 3 4 5 6 7 8 9 10) + (loop for x below 10 collect x) + => (0 1 2 3 4 5 6 7 8 9) + + The `by' value is always positive, even for downward-counting + loops. Some sort of `from' value is required for downward loops; + `for x downto 5' is not a legal loop clause all by itself. + +`for VAR in LIST by FUNCTION' + This clause iterates VAR over all the elements of LIST, in turn. + If you specify the `by' term, then FUNCTION is used to traverse + the list instead of `cdr'; it must be a function taking one + argument. For example: + + (loop for x in '(1 2 3 4 5 6) collect (* x x)) + => (1 4 9 16 25 36) + (loop for x in '(1 2 3 4 5 6) by 'cddr collect (* x x)) + => (1 9 25) + +`for VAR on LIST by FUNCTION' + This clause iterates VAR over all the cons cells of LIST. + + (loop for x on '(1 2 3 4) collect x) + => ((1 2 3 4) (2 3 4) (3 4) (4)) + + With `by', there is no real reason that the `on' expression must + be a list. For example: + + (loop for x on first-animal by 'next-animal collect x) + + where `(next-animal x)' takes an "animal" X and returns the next + in the (assumed) sequence of animals, or `nil' if X was the last + animal in the sequence. + +`for VAR in-ref LIST by FUNCTION' + This is like a regular `in' clause, but VAR becomes a `setf'-able + "reference" onto the elements of the list rather than just a + temporary variable. For example, + + (loop for x in-ref my-list do (incf x)) + + increments every element of `my-list' in place. This clause is an + extension to standard Common Lisp. + +`for VAR across ARRAY' + This clause iterates VAR over all the elements of ARRAY, which may + be a vector or a string. + + (loop for x across "aeiou" + do (use-vowel (char-to-string x))) + +`for VAR across-ref ARRAY' + This clause iterates over an array, with VAR a `setf'-able + reference onto the elements; see `in-ref' above. + +`for VAR being the elements of SEQUENCE' + This clause iterates over the elements of SEQUENCE, which may be a + list, vector, or string. Since the type must be determined at + run-time, this is somewhat less efficient than `in' or `across'. + The clause may be followed by the additional term `using (index + VAR2)' to cause VAR2 to be bound to the successive indices + (starting at 0) of the elements. + + This clause type is taken from older versions of the `loop' macro, + and is not present in modern Common Lisp. The `using (sequence + ...)' term of the older macros is not supported. + +`for VAR being the elements of-ref SEQUENCE' + This clause iterates over a sequence, with VAR a `setf'-able + reference onto the elements; see `in-ref' above. + +`for VAR being the symbols [of OBARRAY]' + This clause iterates over symbols, either over all interned symbols + or over all symbols in OBARRAY. The loop is executed with VAR + bound to each symbol in turn. The symbols are visited in an + unspecified order. + + As an example, + + (loop for sym being the symbols + when (fboundp sym) + when (string-match "^map" (symbol-name sym)) + collect sym) + + returns a list of all the functions whose names begin with `map'. + + The Common Lisp words `external-symbols' and `present-symbols' are + also recognized but are equivalent to `symbols' in Emacs Lisp. + + Due to a minor implementation restriction, it will not work to have + more than one `for' clause iterating over symbols, hash tables, + keymaps, overlays, or intervals in a given `loop'. Fortunately, + it would rarely if ever be useful to do so. It _is_ legal to mix + one of these types of clauses with other clauses like `for ... to' + or `while'. + +`for VAR being the hash-keys of HASH-TABLE' + This clause iterates over the entries in HASH-TABLE. For each + hash table entry, VAR is bound to the entry's key. If you write + `the hash-values' instead, VAR is bound to the values of the + entries. The clause may be followed by the additional term `using + (hash-values VAR2)' (where `hash-values' is the opposite word of + the word following `the') to cause VAR and VAR2 to be bound to the + two parts of each hash table entry. + +`for VAR being the key-codes of KEYMAP' + This clause iterates over the entries in KEYMAP. In GNU Emacs 18 + and 19, keymaps are either alists or vectors, and key-codes are + integers or symbols. In XEmacs, keymaps are a special new data + type, and key-codes are symbols or lists of symbols. The + iteration does not enter nested keymaps or inherited (parent) + keymaps. You can use `the key-bindings' to access the commands + bound to the keys rather than the key codes, and you can add a + `using' clause to access both the codes and the bindings together. + +`for VAR being the key-seqs of KEYMAP' + This clause iterates over all key sequences defined by KEYMAP and + its nested keymaps, where VAR takes on values which are strings in + Emacs 18 or vectors in Emacs 19. The strings or vectors are + reused for each iteration, so you must copy them if you wish to + keep them permanently. You can add a `using (key-bindings ...)' + clause to get the command bindings as well. + +`for VAR being the overlays [of BUFFER] ...' + This clause iterates over the Emacs 19 "overlays" or XEmacs + "extents" of a buffer (the clause `extents' is synonymous with + `overlays'). Under Emacs 18, this clause iterates zero times. If + the `of' term is omitted, the current buffer is used. This clause + also accepts optional `from POS' and `to POS' terms, limiting the + clause to overlays which overlap the specified region. + +`for VAR being the intervals [of BUFFER] ...' + This clause iterates over all intervals of a buffer with constant + text properties. The variable VAR will be bound to conses of + start and end positions, where one start position is always equal + to the previous end position. The clause allows `of', `from', + `to', and `property' terms, where the latter term restricts the + search to just the specified property. The `of' term may specify + either a buffer or a string. This clause is useful only in GNU + Emacs 19; in other versions, all buffers and strings consist of a + single interval. + +`for VAR being the frames' + This clause iterates over all frames, i.e., X window system windows + open on Emacs files. This clause works only under Emacs 19. The + clause `screens' is a synonym for `frames'. The frames are + visited in `next-frame' order starting from `selected-frame'. + +`for VAR being the windows [of FRAME]' + This clause iterates over the windows (in the Emacs sense) of the + current frame, or of the specified FRAME. (In Emacs 18 there is + only ever one frame, and the `of' term is not allowed there.) + +`for VAR being the buffers' + This clause iterates over all buffers in Emacs. It is equivalent + to `for VAR in (buffer-list)'. + +`for VAR = EXPR1 then EXPR2' + This clause does a general iteration. The first time through the + loop, VAR will be bound to EXPR1. On the second and successive + iterations it will be set by evaluating EXPR2 (which may refer to + the old value of VAR). For example, these two loops are + effectively the same: + + (loop for x on my-list by 'cddr do ...) + (loop for x = my-list then (cddr x) while x do ...) + + Note that this type of `for' clause does not imply any sort of + terminating condition; the above example combines it with a + `while' clause to tell when to end the loop. + + If you omit the `then' term, EXPR1 is used both for the initial + setting and for successive settings: + + (loop for x = (random) when (> x 0) return x) + + This loop keeps taking random numbers from the `(random)' function + until it gets a positive one, which it then returns. + + If you include several `for' clauses in a row, they are treated +sequentially (as if by `let*' and `setq'). You can instead use the +word `and' to link the clauses, in which case they are processed in +parallel (as if by `let' and `psetq'). + + (loop for x below 5 for y = nil then x collect (list x y)) + => ((0 nil) (1 1) (2 2) (3 3) (4 4)) + (loop for x below 5 and y = nil then x collect (list x y)) + => ((0 nil) (1 0) (2 1) (3 2) (4 3)) + +In the first loop, `y' is set based on the value of `x' that was just +set by the previous clause; in the second loop, `x' and `y' are set +simultaneously so `y' is set based on the value of `x' left over from +the previous time through the loop. + + Another feature of the `loop' macro is "destructuring", similar in +concept to the destructuring provided by `defmacro'. The VAR part of +any `for' clause can be given as a list of variables instead of a +single variable. The values produced during loop execution must be +lists; the values in the lists are stored in the corresponding +variables. + + (loop for (x y) in '((2 3) (4 5) (6 7)) collect (+ x y)) + => (5 9 13) + + In loop destructuring, if there are more values than variables the +trailing values are ignored, and if there are more variables than +values the trailing variables get the value `nil'. If `nil' is used as +a variable name, the corresponding values are ignored. Destructuring +may be nested, and dotted lists of variables like `(x . y)' are allowed. + + +File: cl.info, Node: Iteration Clauses, Next: Accumulation Clauses, Prev: For Clauses, Up: Loop Facility + +Iteration Clauses +----------------- + +Aside from `for' clauses, there are several other loop clauses that +control the way the loop operates. They might be used by themselves, +or in conjunction with one or more `for' clauses. + +`repeat INTEGER' + This clause simply counts up to the specified number using an + internal temporary variable. The loops + + (loop repeat n do ...) + (loop for temp to n do ...) + + are identical except that the second one forces you to choose a + name for a variable you aren't actually going to use. + +`while CONDITION' + This clause stops the loop when the specified condition (any Lisp + expression) becomes `nil'. For example, the following two loops + are equivalent, except for the implicit `nil' block that surrounds + the second one: + + (while COND FORMS...) + (loop while COND do FORMS...) + +`until CONDITION' + This clause stops the loop when the specified condition is true, + i.e., non-`nil'. + +`always CONDITION' + This clause stops the loop when the specified condition is `nil'. + Unlike `while', it stops the loop using `return nil' so that the + `finally' clauses are not executed. If all the conditions were + non-`nil', the loop returns `t': + + (if (loop for size in size-list always (> size 10)) + (some-big-sizes) + (no-big-sizes)) + +`never CONDITION' + This clause is like `always', except that the loop returns `t' if + any conditions were false, or `nil' otherwise. + +`thereis CONDITION' + This clause stops the loop when the specified form is non-`nil'; + in this case, it returns that non-`nil' value. If all the values + were `nil', the loop returns `nil'. + + +File: cl.info, Node: Accumulation Clauses, Next: Other Clauses, Prev: Iteration Clauses, Up: Loop Facility + +Accumulation Clauses +-------------------- + +These clauses cause the loop to accumulate information about the +specified Lisp FORM. The accumulated result is returned from the loop +unless overridden, say, by a `return' clause. + +`collect FORM' + This clause collects the values of FORM into a list. Several + examples of `collect' appear elsewhere in this manual. + + The word `collecting' is a synonym for `collect', and likewise for + the other accumulation clauses. + +`append FORM' + This clause collects lists of values into a result list using + `append'. + +`nconc FORM' + This clause collects lists of values into a result list by + destructively modifying the lists rather than copying them. + +`concat FORM' + This clause concatenates the values of the specified FORM into a + string. (It and the following clause are extensions to standard + Common Lisp.) + +`vconcat FORM' + This clause concatenates the values of the specified FORM into a + vector. + +`count FORM' + This clause counts the number of times the specified FORM + evaluates to a non-`nil' value. + +`sum FORM' + This clause accumulates the sum of the values of the specified + FORM, which must evaluate to a number. + +`maximize FORM' + This clause accumulates the maximum value of the specified FORM, + which must evaluate to a number. The return value is undefined if + `maximize' is executed zero times. + +`minimize FORM' + This clause accumulates the minimum value of the specified FORM. + + Accumulation clauses can be followed by `into VAR' to cause the data +to be collected into variable VAR (which is automatically `let'-bound +during the loop) rather than an unnamed temporary variable. Also, +`into' accumulations do not automatically imply a return value. The +loop must use some explicit mechanism, such as `finally return', to +return the accumulated result. + + It is legal for several accumulation clauses of the same type to +accumulate into the same place. From Steele: + + (loop for name in '(fred sue alice joe june) + for kids in '((bob ken) () () (kris sunshine) ()) + collect name + append kids) + => (fred bob ken sue alice joe kris sunshine june) + + +File: cl.info, Node: Other Clauses, Prev: Accumulation Clauses, Up: Loop Facility + +Other Clauses +------------- + +This section describes the remaining loop clauses. + +`with VAR = VALUE' + This clause binds a variable to a value around the loop, but + otherwise leaves the variable alone during the loop. The following + loops are basically equivalent: + + (loop with x = 17 do ...) + (let ((x 17)) (loop do ...)) + (loop for x = 17 then x do ...) + + Naturally, the variable VAR might be used for some purpose in the + rest of the loop. For example: + + (loop for x in my-list with res = nil do (push x res) + finally return res) + + This loop inserts the elements of `my-list' at the front of a new + list being accumulated in `res', then returns the list `res' at + the end of the loop. The effect is similar to that of a `collect' + clause, but the list gets reversed by virtue of the fact that + elements are being pushed onto the front of `res' rather than the + end. + + If you omit the `=' term, the variable is initialized to `nil'. + (Thus the `= nil' in the above example is unnecessary.) + + Bindings made by `with' are sequential by default, as if by + `let*'. Just like `for' clauses, `with' clauses can be linked + with `and' to cause the bindings to be made by `let' instead. + +`if CONDITION CLAUSE' + This clause executes the following loop clause only if the + specified condition is true. The following CLAUSE should be an + accumulation, `do', `return', `if', or `unless' clause. Several + clauses may be linked by separating them with `and'. These + clauses may be followed by `else' and a clause or clauses to + execute if the condition was false. The whole construct may + optionally be followed by the word `end' (which may be used to + disambiguate an `else' or `and' in a nested `if'). + + The actual non-`nil' value of the condition form is available by + the name `it' in the "then" part. For example: + + (setq funny-numbers '(6 13 -1)) + => (6 13 -1) + (loop for x below 10 + if (oddp x) + collect x into odds + and if (memq x funny-numbers) return (cdr it) end + else + collect x into evens + finally return (vector odds evens)) + => [(1 3 5 7 9) (0 2 4 6 8)] + (setq funny-numbers '(6 7 13 -1)) + => (6 7 13 -1) + (loop ) + => (13 -1) + + Note the use of `and' to put two clauses into the "then" part, one + of which is itself an `if' clause. Note also that `end', while + normally optional, was necessary here to make it clear that the + `else' refers to the outermost `if' clause. In the first case, + the loop returns a vector of lists of the odd and even values of + X. In the second case, the odd number 7 is one of the + `funny-numbers' so the loop returns early; the actual returned + value is based on the result of the `memq' call. + +`when CONDITION CLAUSE' + This clause is just a synonym for `if'. + +`unless CONDITION CLAUSE' + The `unless' clause is just like `if' except that the sense of the + condition is reversed. + +`named NAME' + This clause gives a name other than `nil' to the implicit block + surrounding the loop. The NAME is the symbol to be used as the + block name. + +`initially [do] FORMS...' + This keyword introduces one or more Lisp forms which will be + executed before the loop itself begins (but after any variables + requested by `for' or `with' have been bound to their initial + values). `initially' clauses can appear anywhere; if there are + several, they are executed in the order they appear in the loop. + The keyword `do' is optional. + +`finally [do] FORMS...' + This introduces Lisp forms which will be executed after the loop + finishes (say, on request of a `for' or `while'). `initially' and + `finally' clauses may appear anywhere in the loop construct, but + they are executed (in the specified order) at the beginning or + end, respectively, of the loop. + +`finally return FORM' + This says that FORM should be executed after the loop is done to + obtain a return value. (Without this, or some other clause like + `collect' or `return', the loop will simply return `nil'.) + Variables bound by `for', `with', or `into' will still contain + their final values when FORM is executed. + +`do FORMS...' + The word `do' may be followed by any number of Lisp expressions + which are executed as an implicit `progn' in the body of the loop. + Many of the examples in this section illustrate the use of `do'. + +`return FORM' + This clause causes the loop to return immediately. The following + Lisp form is evaluated to give the return value of the `loop' + form. The `finally' clauses, if any, are not executed. Of + course, `return' is generally used inside an `if' or `unless', as + its use in a top-level loop clause would mean the loop would never + get to "loop" more than once. + + The clause `return FORM' is equivalent to `do (return FORM)' (or + `return-from' if the loop was named). The `return' clause is + implemented a bit more efficiently, though. + + While there is no high-level way to add user extensions to `loop' +(comparable to `defsetf' for `setf', say), this package does offer two +properties called `cl-loop-handler' and `cl-loop-for-handler' which are +functions to be called when a given symbol is encountered as a +top-level loop clause or `for' clause, respectively. Consult the +source code in file `cl-macs.el' for details. + + This package's `loop' macro is compatible with that of Common Lisp, +except that a few features are not implemented: `loop-finish' and +data-type specifiers. Naturally, the `for' clauses which iterate over +keymaps, overlays, intervals, frames, windows, and buffers are +Emacs-specific extensions. + + +File: cl.info, Node: Multiple Values, Prev: Loop Facility, Up: Control Structure + +Multiple Values +=============== + +Common Lisp functions can return zero or more results. Emacs Lisp +functions, by contrast, always return exactly one result. This package +makes no attempt to emulate Common Lisp multiple return values; Emacs +versions of Common Lisp functions that return more than one value +either return just the first value (as in `compiler-macroexpand') or +return a list of values (as in `get-setf-method'). This package _does_ +define placeholders for the Common Lisp functions that work with +multiple values, but in Emacs Lisp these functions simply operate on +lists instead. The `values' form, for example, is a synonym for `list' +in Emacs. + + - Special Form: multiple-value-bind (var...) values-form forms... + This form evaluates VALUES-FORM, which must return a list of + values. It then binds the VARs to these respective values, as if + by `let', and then executes the body FORMS. If there are more + VARs than values, the extra VARs are bound to `nil'. If there are + fewer VARs than values, the excess values are ignored. + + - Special Form: multiple-value-setq (var...) form + This form evaluates FORM, which must return a list of values. It + then sets the VARs to these respective values, as if by `setq'. + Extra VARs or values are treated the same as in + `multiple-value-bind'. + + The older Quiroz package attempted a more faithful (but still +imperfect) emulation of Common Lisp multiple values. The old method +"usually" simulated true multiple values quite well, but under certain +circumstances would leave spurious return values in memory where a +later, unrelated `multiple-value-bind' form would see them. + + Since a perfect emulation is not feasible in Emacs Lisp, this +package opts to keep it as simple and predictable as possible. + + +File: cl.info, Node: Macros, Next: Declarations, Prev: Control Structure, Up: Top + +Macros +****** + +This package implements the various Common Lisp features of `defmacro', +such as destructuring, `&environment', and `&body'. Top-level `&whole' +is not implemented for `defmacro' due to technical difficulties. *Note +Argument Lists::. + + Destructuring is made available to the user by way of the following +macro: + + - Special Form: destructuring-bind arglist expr forms... + This macro expands to code which executes FORMS, with the + variables in ARGLIST bound to the list of values returned by EXPR. + The ARGLIST can include all the features allowed for `defmacro' + argument lists, including destructuring. (The `&environment' + keyword is not allowed.) The macro expansion will signal an error + if EXPR returns a list of the wrong number of arguments or with + incorrect keyword arguments. + + This package also includes the Common Lisp `define-compiler-macro' +facility, which allows you to define compile-time expansions and +optimizations for your functions. + + - Special Form: define-compiler-macro name arglist forms... + This form is similar to `defmacro', except that it only expands + calls to NAME at compile-time; calls processed by the Lisp + interpreter are not expanded, nor are they expanded by the + `macroexpand' function. + + The argument list may begin with a `&whole' keyword and a + variable. This variable is bound to the macro-call form itself, + i.e., to a list of the form `(NAME ARGS...)'. If the macro + expander returns this form unchanged, then the compiler treats it + as a normal function call. This allows compiler macros to work as + optimizers for special cases of a function, leaving complicated + cases alone. + + For example, here is a simplified version of a definition that + appears as a standard part of this package: + + (define-compiler-macro member* (&whole form a list &rest keys) + (if (and (null keys) + (eq (car-safe a) 'quote) + (not (floatp-safe (cadr a)))) + (list 'memq a list) + form)) + + This definition causes `(member* A LIST)' to change to a call to + the faster `memq' in the common case where A is a + non-floating-point constant; if A is anything else, or if there + are any keyword arguments in the call, then the original `member*' + call is left intact. (The actual compiler macro for `member*' + optimizes a number of other cases, including common `:test' + predicates.) + + - Function: compiler-macroexpand form + This function is analogous to `macroexpand', except that it + expands compiler macros rather than regular macros. It returns + FORM unchanged if it is not a call to a function for which a + compiler macro has been defined, or if that compiler macro decided + to punt by returning its `&whole' argument. Like `macroexpand', + it expands repeatedly until it reaches a form for which no further + expansion is possible. + + *Note Macro Bindings::, for descriptions of the `macrolet' and +`symbol-macrolet' forms for making "local" macro definitions. + + +File: cl.info, Node: Declarations, Next: Symbols, Prev: Macros, Up: Top + +Declarations +************ + +Common Lisp includes a complex and powerful "declaration" mechanism +that allows you to give the compiler special hints about the types of +data that will be stored in particular variables, and about the ways +those variables and functions will be used. This package defines +versions of all the Common Lisp declaration forms: `declare', +`locally', `proclaim', `declaim', and `the'. + + Most of the Common Lisp declarations are not currently useful in +Emacs Lisp, as the byte-code system provides little opportunity to +benefit from type information, and `special' declarations are redundant +in a fully dynamically-scoped Lisp. A few declarations are meaningful +when the optimizing Emacs 19 byte compiler is being used, however. +Under the earlier non-optimizing compiler, these declarations will +effectively be ignored. + + - Function: proclaim decl-spec + This function records a "global" declaration specified by + DECL-SPEC. Since `proclaim' is a function, DECL-SPEC is evaluated + and thus should normally be quoted. + + - Special Form: declaim decl-specs... + This macro is like `proclaim', except that it takes any number of + DECL-SPEC arguments, and the arguments are unevaluated and + unquoted. The `declaim' macro also puts an `(eval-when (compile + load eval) ...)' around the declarations so that they will be + registered at compile-time as well as at run-time. (This is vital, + since normally the declarations are meant to influence the way the + compiler treats the rest of the file that contains the `declaim' + form.) + + - Special Form: declare decl-specs... + This macro is used to make declarations within functions and other + code. Common Lisp allows declarations in various locations, + generally at the beginning of any of the many "implicit `progn's" + throughout Lisp syntax, such as function bodies, `let' bodies, + etc. Currently the only declaration understood by `declare' is + `special'. + + - Special Form: locally declarations... forms... + In this package, `locally' is no different from `progn'. + + - Special Form: the type form + Type information provided by `the' is ignored in this package; in + other words, `(the TYPE FORM)' is equivalent to FORM. Future + versions of the optimizing byte-compiler may make use of this + information. + + For example, `mapcar' can map over both lists and arrays. It is + hard for the compiler to expand `mapcar' into an in-line loop + unless it knows whether the sequence will be a list or an array + ahead of time. With `(mapcar 'car (the vector foo))', a future + compiler would have enough information to expand the loop in-line. + For now, Emacs Lisp will treat the above code as exactly equivalent + to `(mapcar 'car foo)'. + + Each DECL-SPEC in a `proclaim', `declaim', or `declare' should be a +list beginning with a symbol that says what kind of declaration it is. +This package currently understands `special', `inline', `notinline', +`optimize', and `warn' declarations. (The `warn' declaration is an +extension of standard Common Lisp.) Other Common Lisp declarations, +such as `type' and `ftype', are silently ignored. + +`special' + Since all variables in Emacs Lisp are "special" (in the Common + Lisp sense), `special' declarations are only advisory. They + simply tell the optimizing byte compiler that the specified + variables are intentionally being referred to without being bound + in the body of the function. The compiler normally emits warnings + for such references, since they could be typographical errors for + references to local variables. + + The declaration `(declare (special VAR1 VAR2))' is equivalent to + `(defvar VAR1) (defvar VAR2)' in the optimizing compiler, or to + nothing at all in older compilers (which do not warn for non-local + references). + + In top-level contexts, it is generally better to write `(defvar + VAR)' than `(declaim (special VAR))', since `defvar' makes your + intentions clearer. But the older byte compilers can not handle + `defvar's appearing inside of functions, while `(declare (special + VAR))' takes care to work correctly with all compilers. + +`inline' + The `inline' DECL-SPEC lists one or more functions whose bodies + should be expanded "in-line" into calling functions whenever the + compiler is able to arrange for it. For example, the Common Lisp + function `cadr' is declared `inline' by this package so that the + form `(cadr X)' will expand directly into `(car (cdr X))' when it + is called in user functions, for a savings of one (relatively + expensive) function call. + + The following declarations are all equivalent. Note that the + `defsubst' form is a convenient way to define a function and + declare it inline all at once, but it is available only in Emacs + 19. + + (declaim (inline foo bar)) + (eval-when (compile load eval) (proclaim '(inline foo bar))) + (proclaim-inline foo bar) ; XEmacs only + (defsubst foo (...) ...) ; instead of defun; Emacs 19 only + + *Please note:* This declaration remains in effect after the + containing source file is done. It is correct to use it to + request that a function you have defined should be inlined, but it + is impolite to use it to request inlining of an external function. + + In Common Lisp, it is possible to use `(declare (inline ...))' + before a particular call to a function to cause just that call to + be inlined; the current byte compilers provide no way to implement + this, so `(declare (inline ...))' is currently ignored by this + package. + +`notinline' + The `notinline' declaration lists functions which should not be + inlined after all; it cancels a previous `inline' declaration. + +`optimize' + This declaration controls how much optimization is performed by + the compiler. Naturally, it is ignored by the earlier + non-optimizing compilers. + + The word `optimize' is followed by any number of lists like + `(speed 3)' or `(safety 2)'. Common Lisp defines several + optimization "qualities"; this package ignores all but `speed' and + `safety'. The value of a quality should be an integer from 0 to + 3, with 0 meaning "unimportant" and 3 meaning "very important." + The default level for both qualities is 1. + + In this package, with the Emacs 19 optimizing compiler, the + `speed' quality is tied to the `byte-compile-optimize' flag, which + is set to `nil' for `(speed 0)' and to `t' for higher settings; + and the `safety' quality is tied to the + `byte-compile-delete-errors' flag, which is set to `t' for + `(safety 3)' and to `nil' for all lower settings. (The latter + flag controls whether the compiler is allowed to optimize out code + whose only side-effect could be to signal an error, e.g., + rewriting `(progn foo bar)' to `bar' when it is not known whether + `foo' will be bound at run-time.) + + Note that even compiling with `(safety 0)', the Emacs byte-code + system provides sufficient checking to prevent real harm from + being done. For example, barring serious bugs in Emacs itself, + Emacs will not crash with a segmentation fault just because of an + error in a fully-optimized Lisp program. + + The `optimize' declaration is normally used in a top-level + `proclaim' or `declaim' in a file; Common Lisp allows it to be + used with `declare' to set the level of optimization locally for a + given form, but this will not work correctly with the current + version of the optimizing compiler. (The `declare' will set the + new optimization level, but that level will not automatically be + unset after the enclosing form is done.) + +`warn' + This declaration controls what sorts of warnings are generated by + the byte compiler. Again, only the optimizing compiler generates + warnings. The word `warn' is followed by any number of "warning + qualities," similar in form to optimization qualities. The + currently supported warning types are `redefine', `callargs', + `unresolved', and `free-vars'; in the current system, a value of 0 + will disable these warnings and any higher value will enable them. + See the documentation for the optimizing byte compiler for details. + + +File: cl.info, Node: Symbols, Next: Numbers, Prev: Declarations, Up: Top + +Symbols +******* + +This package defines several symbol-related features that were missing +from Emacs Lisp. + +* Menu: + +* Property Lists:: `getf', `remf' +* Creating Symbols:: `gensym', `gentemp' + + +File: cl.info, Node: Property Lists, Next: Creating Symbols, Prev: Symbols, Up: Symbols + +Property Lists +============== + +These functions augment the standard Emacs Lisp functions `get' and +`put' for operating on properties attached to objects. There are also +functions for working with property lists as first-class data +structures not attached to particular objects. + + - Function: getf place property &optional default + This function scans the list PLACE as if it were a property list, + i.e., a list of alternating property names and values. If an + even-numbered element of PLACE is found which is `eq' to PROPERTY, + the following odd-numbered element is returned. Otherwise, + DEFAULT is returned (or `nil' if no default is given). + + In particular, + + (get sym prop) == (getf (symbol-plist sym) prop) + + It is legal to use `getf' as a `setf' place, in which case its + PLACE argument must itself be a legal `setf' place. The DEFAULT + argument, if any, is ignored in this context. The effect is to + change (via `setcar') the value cell in the list that corresponds + to PROPERTY, or to cons a new property-value pair onto the list if + the property is not yet present. + + (put sym prop val) == (setf (getf (symbol-plist sym) prop) val) + + The `get' function is also `setf'-able. The fact that `default' + is ignored can sometimes be useful: + + (incf (get 'foo 'usage-count 0)) + + Here, symbol `foo''s `usage-count' property is incremented if it + exists, or set to 1 (an incremented 0) otherwise. + + When not used as a `setf' form, `getf' is just a regular function + and its PLACE argument can actually be any Lisp expression. + + - Special Form: remf place property + This macro removes the property-value pair for PROPERTY from the + property list stored at PLACE, which is any `setf'-able place + expression. It returns true if the property was found. Note that + if PROPERTY happens to be first on the list, this will effectively + do a `(setf PLACE (cddr PLACE))', whereas if it occurs later, this + simply uses `setcdr' to splice out the property and value cells. + + +File: cl.info, Node: Creating Symbols, Prev: Property Lists, Up: Symbols + +Creating Symbols +================ + +These functions create unique symbols, typically for use as temporary +variables. + + - Function: gensym &optional x + This function creates a new, uninterned symbol (using + `make-symbol') with a unique name. (The name of an uninterned + symbol is relevant only if the symbol is printed.) By default, + the name is generated from an increasing sequence of numbers, + `G1000', `G1001', `G1002', etc. If the optional argument X is a + string, that string is used as a prefix instead of `G'. + Uninterned symbols are used in macro expansions for temporary + variables, to ensure that their names will not conflict with + "real" variables in the user's code. + + - Variable: *gensym-counter* + This variable holds the counter used to generate `gensym' names. + It is incremented after each use by `gensym'. In Common Lisp this + is initialized with 0, but this package initializes it with a + random (time-dependent) value to avoid trouble when two files that + each used `gensym' in their compilation are loaded together. + + *XEmacs note:* As of XEmacs 21.0, an uninterned symbol remains + uninterned even after being dumped to bytecode. Older versions of + Emacs didn't distinguish the printed representation of interned + and uninterned symbols, so their names had to be treated more + carefully. + + - Function: gentemp &optional x + This function is like `gensym', except that it produces a new + _interned_ symbol. If the symbol that is generated already + exists, the function keeps incrementing the counter and trying + again until a new symbol is generated. + + The Quiroz `cl.el' package also defined a `defkeyword' form for +creating self-quoting keyword symbols. This package automatically +creates all keywords that are called for by `&key' argument specifiers, +and discourages the use of keywords as data unrelated to keyword +arguments, so the `defkeyword' form has been discontinued. + + +File: cl.info, Node: Numbers, Next: Sequences, Prev: Symbols, Up: Top + +Numbers +******* + +This section defines a few simple Common Lisp operations on numbers +which were left out of Emacs Lisp. + +* Menu: + +* Predicates on Numbers:: `plusp', `oddp', `floatp-safe', etc. +* Numerical Functions:: `abs', `expt', `floor*', etc. +* Random Numbers:: `random*', `make-random-state' +* Implementation Parameters:: `most-positive-fixnum', `most-positive-float' + + +File: cl.info, Node: Predicates on Numbers, Next: Numerical Functions, Prev: Numbers, Up: Numbers + +Predicates on Numbers +===================== + +These functions return `t' if the specified condition is true of the +numerical argument, or `nil' otherwise. + + - Function: plusp number + This predicate tests whether NUMBER is positive. It is an error + if the argument is not a number. + + - Function: minusp number + This predicate tests whether NUMBER is negative. It is an error + if the argument is not a number. + + - Function: oddp integer + This predicate tests whether INTEGER is odd. It is an error if + the argument is not an integer. + + - Function: evenp integer + This predicate tests whether INTEGER is even. It is an error if + the argument is not an integer. + + - Function: floatp-safe object + This predicate tests whether OBJECT is a floating-point number. + On systems that support floating-point, this is equivalent to + `floatp'. On other systems, this always returns `nil'. + + +File: cl.info, Node: Numerical Functions, Next: Random Numbers, Prev: Predicates on Numbers, Up: Numbers + +Numerical Functions +=================== + +These functions perform various arithmetic operations on numbers. + + - Function: abs number + This function returns the absolute value of NUMBER. (Newer + versions of Emacs provide this as a built-in function; this package + defines `abs' only for Emacs 18 versions which don't provide it as + a primitive.) + + - Function: expt base power + This function returns BASE raised to the power of NUMBER. (Newer + versions of Emacs provide this as a built-in function; this + package defines `expt' only for Emacs 18 versions which don't + provide it as a primitive.) + + - Function: gcd &rest integers + This function returns the Greatest Common Divisor of the arguments. + For one argument, it returns the absolute value of that argument. + For zero arguments, it returns zero. + + - Function: lcm &rest integers + This function returns the Least Common Multiple of the arguments. + For one argument, it returns the absolute value of that argument. + For zero arguments, it returns one. + + - Function: isqrt integer + This function computes the "integer square root" of its integer + argument, i.e., the greatest integer less than or equal to the true + square root of the argument. + + - Function: floor* number &optional divisor + This function implements the Common Lisp `floor' function. It is + called `floor*' to avoid name conflicts with the simpler `floor' + function built-in to Emacs 19. + + With one argument, `floor*' returns a list of two numbers: The + argument rounded down (toward minus infinity) to an integer, and + the "remainder" which would have to be added back to the first + return value to yield the argument again. If the argument is an + integer X, the result is always the list `(X 0)'. If the argument + is an Emacs 19 floating-point number, the first result is a Lisp + integer and the second is a Lisp float between 0 (inclusive) and 1 + (exclusive). + + With two arguments, `floor*' divides NUMBER by DIVISOR, and + returns the floor of the quotient and the corresponding remainder + as a list of two numbers. If `(floor* X Y)' returns `(Q R)', then + `Q*Y + R = X', with R between 0 (inclusive) and R (exclusive). + Also, note that `(floor* X)' is exactly equivalent to `(floor* X + 1)'. + + This function is entirely compatible with Common Lisp's `floor' + function, except that it returns the two results in a list since + Emacs Lisp does not support multiple-valued functions. + + - Function: ceiling* number &optional divisor + This function implements the Common Lisp `ceiling' function, which + is analogous to `floor' except that it rounds the argument or + quotient of the arguments up toward plus infinity. The remainder + will be between 0 and minus R. + + - Function: truncate* number &optional divisor + This function implements the Common Lisp `truncate' function, + which is analogous to `floor' except that it rounds the argument + or quotient of the arguments toward zero. Thus it is equivalent + to `floor*' if the argument or quotient is positive, or to + `ceiling*' otherwise. The remainder has the same sign as NUMBER. + + - Function: round* number &optional divisor + This function implements the Common Lisp `round' function, which + is analogous to `floor' except that it rounds the argument or + quotient of the arguments to the nearest integer. In the case of + a tie (the argument or quotient is exactly halfway between two + integers), it rounds to the even integer. + + - Function: mod* number divisor + This function returns the same value as the second return value of + `floor'. + + - Function: rem* number divisor + This function returns the same value as the second return value of + `truncate'. + + These definitions are compatible with those in the Quiroz `cl.el' +package, except that this package appends `*' to certain function names +to avoid conflicts with existing Emacs 19 functions, and that the +mechanism for returning multiple values is different. + + +File: cl.info, Node: Random Numbers, Next: Implementation Parameters, Prev: Numerical Functions, Up: Numbers + +Random Numbers +============== + +This package also provides an implementation of the Common Lisp random +number generator. It uses its own additive-congruential algorithm, +which is much more likely to give statistically clean random numbers +than the simple generators supplied by many operating systems. + + - Function: random* number &optional state + This function returns a random nonnegative number less than + NUMBER, and of the same type (either integer or floating-point). + The STATE argument should be a `random-state' object which holds + the state of the random number generator. The function modifies + this state object as a side effect. If STATE is omitted, it + defaults to the variable `*random-state*', which contains a + pre-initialized `random-state' object. + + - Variable: *random-state* + This variable contains the system "default" `random-state' object, + used for calls to `random*' that do not specify an alternative + state object. Since any number of programs in the Emacs process + may be accessing `*random-state*' in interleaved fashion, the + sequence generated from this variable will be irreproducible for + all intents and purposes. + + - Function: make-random-state &optional state + This function creates or copies a `random-state' object. If STATE + is omitted or `nil', it returns a new copy of `*random-state*'. + This is a copy in the sense that future sequences of calls to + `(random* N)' and `(random* N S)' (where S is the new random-state + object) will return identical sequences of random numbers. + + If STATE is a `random-state' object, this function returns a copy + of that object. If STATE is `t', this function returns a new + `random-state' object seeded from the date and time. As an + extension to Common Lisp, STATE may also be an integer in which + case the new object is seeded from that integer; each different + integer seed will result in a completely different sequence of + random numbers. + + It is legal to print a `random-state' object to a buffer or file + and later read it back with `read'. If a program wishes to use a + sequence of pseudo-random numbers which can be reproduced later + for debugging, it can call `(make-random-state t)' to get a new + sequence, then print this sequence to a file. When the program is + later rerun, it can read the original run's random-state from the + file. + + - Function: random-state-p object + This predicate returns `t' if OBJECT is a `random-state' object, + or `nil' otherwise. + + +File: cl.info, Node: Implementation Parameters, Prev: Random Numbers, Up: Numbers + +Implementation Parameters +========================= + +This package defines several useful constants having to with numbers. + + - Variable: most-positive-fixnum + This constant equals the largest value a Lisp integer can hold. + It is typically `2^23-1' or `2^25-1'. + + - Variable: most-negative-fixnum + This constant equals the smallest (most negative) value a Lisp + integer can hold. + + The following parameters have to do with floating-point numbers. +This package determines their values by exercising the computer's +floating-point arithmetic in various ways. Because this operation +might be slow, the code for initializing them is kept in a separate +function that must be called before the parameters can be used. + + - Function: cl-float-limits + This function makes sure that the Common Lisp floating-point + parameters like `most-positive-float' have been initialized. + Until it is called, these parameters will be `nil'. If this + version of Emacs does not support floats (e.g., most versions of + Emacs 18), the parameters will remain `nil'. If the parameters + have already been initialized, the function returns immediately. + + The algorithm makes assumptions that will be valid for most modern + machines, but will fail if the machine's arithmetic is extremely + unusual, e.g., decimal. + + Since true Common Lisp supports up to four different floating-point +precisions, it has families of constants like +`most-positive-single-float', `most-positive-double-float', +`most-positive-long-float', and so on. Emacs has only one +floating-point precision, so this package omits the precision word from +the constants' names. + + - Variable: most-positive-float + This constant equals the largest value a Lisp float can hold. For + those systems whose arithmetic supports infinities, this is the + largest _finite_ value. For IEEE machines, the value is + approximately `1.79e+308'. + + - Variable: most-negative-float + This constant equals the most-negative value a Lisp float can hold. + (It is assumed to be equal to `(- most-positive-float)'.) + + - Variable: least-positive-float + This constant equals the smallest Lisp float value greater than + zero. For IEEE machines, it is about `4.94e-324' if denormals are + supported or `2.22e-308' if not. + + - Variable: least-positive-normalized-float + This constant equals the smallest _normalized_ Lisp float greater + than zero, i.e., the smallest value for which IEEE denormalization + will not result in a loss of precision. For IEEE machines, this + value is about `2.22e-308'. For machines that do not support the + concept of denormalization and gradual underflow, this constant + will always equal `least-positive-float'. + + - Variable: least-negative-float + This constant is the negative counterpart of + `least-positive-float'. + + - Variable: least-negative-normalized-float + This constant is the negative counterpart of + `least-positive-normalized-float'. + + - Variable: float-epsilon + This constant is the smallest positive Lisp float that can be added + to 1.0 to produce a distinct value. Adding a smaller number to 1.0 + will yield 1.0 again due to roundoff. For IEEE machines, epsilon + is about `2.22e-16'. + + - Variable: float-negative-epsilon + This is the smallest positive value that can be subtracted from + 1.0 to produce a distinct value. For IEEE machines, it is about + `1.11e-16'. + + +File: cl.info, Node: Sequences, Next: Lists, Prev: Numbers, Up: Top + +Sequences +********* + +Common Lisp defines a number of functions that operate on "sequences", +which are either lists, strings, or vectors. Emacs Lisp includes a few +of these, notably `elt' and `length'; this package defines most of the +rest. + +* Menu: + +* Sequence Basics:: Arguments shared by all sequence functions +* Mapping over Sequences:: `mapcar*', `mapcan', `map', `every', etc. +* Sequence Functions:: `subseq', `remove*', `substitute', etc. +* Searching Sequences:: `find', `position', `count', `search', etc. +* Sorting Sequences:: `sort*', `stable-sort', `merge' + + +File: cl.info, Node: Sequence Basics, Next: Mapping over Sequences, Prev: Sequences, Up: Sequences + +Sequence Basics +=============== + +Many of the sequence functions take keyword arguments; *note Argument +Lists::. All keyword arguments are optional and, if specified, may +appear in any order. + + The `:key' argument should be passed either `nil', or a function of +one argument. This key function is used as a filter through which the +elements of the sequence are seen; for example, `(find x y :key 'car)' +is similar to `(assoc* x y)': It searches for an element of the list +whose `car' equals `x', rather than for an element which equals `x' +itself. If `:key' is omitted or `nil', the filter is effectively the +identity function. + + The `:test' and `:test-not' arguments should be either `nil', or +functions of two arguments. The test function is used to compare two +sequence elements, or to compare a search value with sequence elements. +(The two values are passed to the test function in the same order as +the original sequence function arguments from which they are derived, +or, if they both come from the same sequence, in the same order as they +appear in that sequence.) The `:test' argument specifies a function +which must return true (non-`nil') to indicate a match; instead, you +may use `:test-not' to give a function which returns _false_ to +indicate a match. The default test function is `:test 'eql'. + + Many functions which take ITEM and `:test' or `:test-not' arguments +also come in `-if' and `-if-not' varieties, where a PREDICATE function +is passed instead of ITEM, and sequence elements match if the predicate +returns true on them (or false in the case of `-if-not'). For example: + + (remove* 0 seq :test '=) == (remove-if 'zerop seq) + +to remove all zeros from sequence `seq'. + + Some operations can work on a subsequence of the argument sequence; +these function take `:start' and `:end' arguments which default to zero +and the length of the sequence, respectively. Only elements between +START (inclusive) and END (exclusive) are affected by the operation. +The END argument may be passed `nil' to signify the length of the +sequence; otherwise, both START and END must be integers, with `0 <= +START <= END <= (length SEQ)'. If the function takes two sequence +arguments, the limits are defined by keywords `:start1' and `:end1' for +the first, and `:start2' and `:end2' for the second. + + A few functions accept a `:from-end' argument, which, if non-`nil', +causes the operation to go from right-to-left through the sequence +instead of left-to-right, and a `:count' argument, which specifies an +integer maximum number of elements to be removed or otherwise processed. + + The sequence functions make no guarantees about the order in which +the `:test', `:test-not', and `:key' functions are called on various +elements. Therefore, it is a bad idea to depend on side effects of +these functions. For example, `:from-end' may cause the sequence to be +scanned actually in reverse, or it may be scanned forwards but +computing a result "as if" it were scanned backwards. (Some functions, +like `mapcar*' and `every', _do_ specify exactly the order in which the +function is called so side effects are perfectly acceptable in those +cases.) + + Strings in GNU Emacs 19 may contain "text properties" as well as +character data. Except as noted, it is undefined whether or not text +properties are preserved by sequence functions. For example, `(remove* +?A STR)' may or may not preserve the properties of the characters +copied from STR into the result. + + +File: cl.info, Node: Mapping over Sequences, Next: Sequence Functions, Prev: Sequence Basics, Up: Sequences + +Mapping over Sequences +====================== + +These functions "map" the function you specify over the elements of +lists or arrays. They are all variations on the theme of the built-in +function `mapcar'. + + - Function: mapcar* function seq &rest more-seqs + This function calls FUNCTION on successive parallel sets of + elements from its argument sequences. Given a single SEQ argument + it is equivalent to `mapcar'; given N sequences, it calls the + function with the first elements of each of the sequences as the N + arguments to yield the first element of the result list, then with + the second elements, and so on. The mapping stops as soon as the + shortest sequence runs out. The argument sequences may be any + mixture of lists, strings, and vectors; the return sequence is + always a list. + + Common Lisp's `mapcar' accepts multiple arguments but works only + on lists; Emacs Lisp's `mapcar' accepts a single sequence + argument. This package's `mapcar*' works as a compatible superset + of both. + + - Function: map result-type function seq &rest more-seqs + This function maps FUNCTION over the argument sequences, just like + `mapcar*', but it returns a sequence of type RESULT-TYPE rather + than a list. RESULT-TYPE must be one of the following symbols: + `vector', `string', `list' (in which case the effect is the same + as for `mapcar*'), or `nil' (in which case the results are thrown + away and `map' returns `nil'). + + - Function: maplist function list &rest more-lists + This function calls FUNCTION on each of its argument lists, then + on the `cdr's of those lists, and so on, until the shortest list + runs out. The results are returned in the form of a list. Thus, + `maplist' is like `mapcar*' except that it passes in the list + pointers themselves rather than the `car's of the advancing + pointers. + + - Function: mapc function seq &rest more-seqs + This function is like `mapcar*', except that the values returned + by FUNCTION are ignored and thrown away rather than being + collected into a list. The return value of `mapc' is SEQ, the + first sequence. + + - Function: mapl function list &rest more-lists + This function is like `maplist', except that it throws away the + values returned by FUNCTION. + + - Function: mapcan function seq &rest more-seqs + This function is like `mapcar*', except that it concatenates the + return values (which must be lists) using `nconc', rather than + simply collecting them into a list. + + - Function: mapcon function list &rest more-lists + This function is like `maplist', except that it concatenates the + return values using `nconc'. + + - Function: some predicate seq &rest more-seqs + This function calls PREDICATE on each element of SEQ in turn; if + PREDICATE returns a non-`nil' value, `some' returns that value, + otherwise it returns `nil'. Given several sequence arguments, it + steps through the sequences in parallel until the shortest one + runs out, just as in `mapcar*'. You can rely on the left-to-right + order in which the elements are visited, and on the fact that + mapping stops immediately as soon as PREDICATE returns non-`nil'. + + - Function: every predicate seq &rest more-seqs + This function calls PREDICATE on each element of the sequence(s) + in turn; it returns `nil' as soon as PREDICATE returns `nil' for + any element, or `t' if the predicate was true for all elements. + + - Function: notany predicate seq &rest more-seqs + This function calls PREDICATE on each element of the sequence(s) + in turn; it returns `nil' as soon as PREDICATE returns a non-`nil' + value for any element, or `t' if the predicate was `nil' for all + elements. + + - Function: notevery predicate seq &rest more-seqs + This function calls PREDICATE on each element of the sequence(s) + in turn; it returns a non-`nil' value as soon as PREDICATE returns + `nil' for any element, or `t' if the predicate was true for all + elements. + + - Function: reduce function seq &key :from-end :start :end + :initial-value :key + This function combines the elements of SEQ using an associative + binary operation. Suppose FUNCTION is `*' and SEQ is the list `(2 + 3 4 5)'. The first two elements of the list are combined with `(* + 2 3) = 6'; this is combined with the next element, `(* 6 4) = 24', + and that is combined with the final element: `(* 24 5) = 120'. + Note that the `*' function happens to be self-reducing, so that + `(* 2 3 4 5)' has the same effect as an explicit call to `reduce'. + + If `:from-end' is true, the reduction is right-associative instead + of left-associative: + + (reduce '- '(1 2 3 4)) + == (- (- (- 1 2) 3) 4) => -8 + (reduce '- '(1 2 3 4) :from-end t) + == (- 1 (- 2 (- 3 4))) => -2 + + If `:key' is specified, it is a function of one argument which is + called on each of the sequence elements in turn. + + If `:initial-value' is specified, it is effectively added to the + front (or rear in the case of `:from-end') of the sequence. The + `:key' function is _not_ applied to the initial value. + + If the sequence, including the initial value, has exactly one + element then that element is returned without ever calling + FUNCTION. If the sequence is empty (and there is no initial + value), then FUNCTION is called with no arguments to obtain the + return value. + + All of these mapping operations can be expressed conveniently in +terms of the `loop' macro. In compiled code, `loop' will be faster +since it generates the loop as in-line code with no function calls. + + +File: cl.info, Node: Sequence Functions, Next: Searching Sequences, Prev: Mapping over Sequences, Up: Sequences + +Sequence Functions +================== + +This section describes a number of Common Lisp functions for operating +on sequences. + + - Function: subseq sequence start &optional end + This function returns a given subsequence of the argument + SEQUENCE, which may be a list, string, or vector. The indices + START and END must be in range, and START must be no greater than + END. If END is omitted, it defaults to the length of the + sequence. The return value is always a copy; it does not share + structure with SEQUENCE. + + As an extension to Common Lisp, START and/or END may be negative, + in which case they represent a distance back from the end of the + sequence. This is for compatibility with Emacs' `substring' + function. Note that `subseq' is the _only_ sequence function that + allows negative START and END. + + You can use `setf' on a `subseq' form to replace a specified range + of elements with elements from another sequence. The replacement + is done as if by `replace', described below. + + - Function: concatenate result-type &rest seqs + This function concatenates the argument sequences together to form + a result sequence of type RESULT-TYPE, one of the symbols + `vector', `string', or `list'. The arguments are always copied, + even in cases such as `(concatenate 'list '(1 2 3))' where the + result is identical to an argument. + + - Function: fill seq item &key :start :end + This function fills the elements of the sequence (or the specified + part of the sequence) with the value ITEM. + + - Function: replace seq1 seq2 &key :start1 :end1 :start2 :end2 + This function copies part of SEQ2 into part of SEQ1. The sequence + SEQ1 is not stretched or resized; the amount of data copied is + simply the shorter of the source and destination (sub)sequences. + The function returns SEQ1. + + If SEQ1 and SEQ2 are `eq', then the replacement will work + correctly even if the regions indicated by the start and end + arguments overlap. However, if SEQ1 and SEQ2 are lists which + share storage but are not `eq', and the start and end arguments + specify overlapping regions, the effect is undefined. + + - Function: remove* item seq &key :test :test-not :key :count :start + :end :from-end + This returns a copy of SEQ with all elements matching ITEM + removed. The result may share storage with or be `eq' to SEQ in + some circumstances, but the original SEQ will not be modified. + The `:test', `:test-not', and `:key' arguments define the matching + test that is used; by default, elements `eql' to ITEM are removed. + The `:count' argument specifies the maximum number of matching + elements that can be removed (only the leftmost COUNT matches are + removed). The `:start' and `:end' arguments specify a region in + SEQ in which elements will be removed; elements outside that + region are not matched or removed. The `:from-end' argument, if + true, says that elements should be deleted from the end of the + sequence rather than the beginning (this matters only if COUNT was + also specified). + + - Function: delete* item seq &key :test :test-not :key :count :start + :end :from-end + This deletes all elements of SEQ which match ITEM. It is a + destructive operation. Since Emacs Lisp does not support + stretchable strings or vectors, this is the same as `remove*' for + those sequence types. On lists, `remove*' will copy the list if + necessary to preserve the original list, whereas `delete*' will + splice out parts of the argument list. Compare `append' and + `nconc', which are analogous non-destructive and destructive list + operations in Emacs Lisp. + + The predicate-oriented functions `remove-if', `remove-if-not', +`delete-if', and `delete-if-not' are defined similarly. + + - Function: delete item list + This MacLisp-compatible function deletes from LIST all elements + which are `equal' to ITEM. The `delete' function is built-in to + Emacs 19; this package defines it equivalently in Emacs 18. + + - Function: remove item list + This function removes from LIST all elements which are `equal' to + ITEM. This package defines it for symmetry with `delete', even + though `remove' is not built-in to Emacs 19. + + - Function: remq item list + This function removes from LIST all elements which are `eq' to + ITEM. This package defines it for symmetry with `delq', even + though `remq' is not built-in to Emacs 19. + + - Function: remove-duplicates seq &key :test :test-not :key :start + :end :from-end + This function returns a copy of SEQ with duplicate elements + removed. Specifically, if two elements from the sequence match + according to the `:test', `:test-not', and `:key' arguments, only + the rightmost one is retained. If `:from-end' is true, the + leftmost one is retained instead. If `:start' or `:end' is + specified, only elements within that subsequence are examined or + removed. + + - Function: delete-duplicates seq &key :test :test-not :key :start + :end :from-end + This function deletes duplicate elements from SEQ. It is a + destructive version of `remove-duplicates'. + + - Function: substitute new old seq &key :test :test-not :key :count + :start :end :from-end + This function returns a copy of SEQ, with all elements matching + OLD replaced with NEW. The `:count', `:start', `:end', and + `:from-end' arguments may be used to limit the number of + substitutions made. + + - Function: nsubstitute new old seq &key :test :test-not :key :count + :start :end :from-end + This is a destructive version of `substitute'; it performs the + substitution using `setcar' or `aset' rather than by returning a + changed copy of the sequence. + + The `substitute-if', `substitute-if-not', `nsubstitute-if', and +`nsubstitute-if-not' functions are defined similarly. For these, a +PREDICATE is given in place of the OLD argument. + + +File: cl.info, Node: Searching Sequences, Next: Sorting Sequences, Prev: Sequence Functions, Up: Sequences + +Searching Sequences +=================== + +These functions search for elements or subsequences in a sequence. +(See also `member*' and `assoc*'; *note Lists::.) + + - Function: find item seq &key :test :test-not :key :start :end + :from-end + This function searches SEQ for an element matching ITEM. If it + finds a match, it returns the matching element. Otherwise, it + returns `nil'. It returns the leftmost match, unless `:from-end' + is true, in which case it returns the rightmost match. The + `:start' and `:end' arguments may be used to limit the range of + elements that are searched. + + - Function: position item seq &key :test :test-not :key :start :end + :from-end + This function is like `find', except that it returns the integer + position in the sequence of the matching item rather than the item + itself. The position is relative to the start of the sequence as + a whole, even if `:start' is non-zero. The function returns `nil' + if no matching element was found. + + - Function: count item seq &key :test :test-not :key :start :end + This function returns the number of elements of SEQ which match + ITEM. The result is always a nonnegative integer. + + The `find-if', `find-if-not', `position-if', `position-if-not', +`count-if', and `count-if-not' functions are defined similarly. + + - Function: mismatch seq1 seq2 &key :test :test-not :key :start1 :end1 + :start2 :end2 :from-end + This function compares the specified parts of SEQ1 and SEQ2. If + they are the same length and the corresponding elements match + (according to `:test', `:test-not', and `:key'), the function + returns `nil'. If there is a mismatch, the function returns the + index (relative to SEQ1) of the first mismatching element. This + will be the leftmost pair of elements which do not match, or the + position at which the shorter of the two otherwise-matching + sequences runs out. + + If `:from-end' is true, then the elements are compared from right + to left starting at `(1- END1)' and `(1- END2)'. If the sequences + differ, then one plus the index of the rightmost difference + (relative to SEQ1) is returned. + + An interesting example is `(mismatch str1 str2 :key 'upcase)', + which compares two strings case-insensitively. + + - Function: search seq1 seq2 &key :test :test-not :key :from-end + :start1 :end1 :start2 :end2 + This function searches SEQ2 for a subsequence that matches SEQ1 + (or part of it specified by `:start1' and `:end1'.) Only matches + which fall entirely within the region defined by `:start2' and + `:end2' will be considered. The return value is the index of the + leftmost element of the leftmost match, relative to the start of + SEQ2, or `nil' if no matches were found. If `:from-end' is true, + the function finds the _rightmost_ matching subsequence. + + +File: cl.info, Node: Sorting Sequences, Prev: Searching Sequences, Up: Sequences + +Sorting Sequences +================= + + - Function: sort* seq predicate &key :key + This function sorts SEQ into increasing order as determined by + using PREDICATE to compare pairs of elements. PREDICATE should + return true (non-`nil') if and only if its first argument is less + than (not equal to) its second argument. For example, `<' and + `string-lessp' are suitable predicate functions for sorting + numbers and strings, respectively; `>' would sort numbers into + decreasing rather than increasing order. + + This function differs from Emacs' built-in `sort' in that it can + operate on any type of sequence, not just lists. Also, it accepts + a `:key' argument which is used to preprocess data fed to the + PREDICATE function. For example, + + (setq data (sort data 'string-lessp :key 'downcase)) + + sorts DATA, a sequence of strings, into increasing alphabetical + order without regard to case. A `:key' function of `car' would be + useful for sorting association lists. + + The `sort*' function is destructive; it sorts lists by actually + rearranging the `cdr' pointers in suitable fashion. + + - Function: stable-sort seq predicate &key :key + This function sorts SEQ "stably", meaning two elements which are + equal in terms of PREDICATE are guaranteed not to be rearranged + out of their original order by the sort. + + In practice, `sort*' and `stable-sort' are equivalent in Emacs + Lisp because the underlying `sort' function is stable by default. + However, this package reserves the right to use non-stable methods + for `sort*' in the future. + + - Function: merge type seq1 seq2 predicate &key :key + This function merges two sequences SEQ1 and SEQ2 by interleaving + their elements. The result sequence, of type TYPE (in the sense + of `concatenate'), has length equal to the sum of the lengths of + the two input sequences. The sequences may be modified + destructively. Order of elements within SEQ1 and SEQ2 is + preserved in the interleaving; elements of the two sequences are + compared by PREDICATE (in the sense of `sort') and the lesser + element goes first in the result. When elements are equal, those + from SEQ1 precede those from SEQ2 in the result. Thus, if SEQ1 + and SEQ2 are both sorted according to PREDICATE, then the result + will be a merged sequence which is (stably) sorted according to + PREDICATE. + + +File: cl.info, Node: Lists, Next: Hash Tables, Prev: Sequences, Up: Top + +Lists +***** + +The functions described here operate on lists. + +* Menu: + +* List Functions:: `caddr', `first', `last', `list*', etc. +* Substitution of Expressions:: `subst', `sublis', etc. +* Lists as Sets:: `member*', `adjoin', `union', etc. +* Association Lists:: `assoc*', `rassoc*', `acons', `pairlis' + + +File: cl.info, Node: List Functions, Next: Substitution of Expressions, Prev: Lists, Up: Lists + +List Functions +============== + +This section describes a number of simple operations on lists, i.e., +chains of cons cells. + + - Function: caddr x + This function is equivalent to `(car (cdr (cdr X)))'. Likewise, + this package defines all 28 `cXXXr' functions where XXX is up to + four `a's and/or `d's. All of these functions are `setf'-able, + and calls to them are expanded inline by the byte-compiler for + maximum efficiency. + + - Function: first x + This function is a synonym for `(car X)'. Likewise, the functions + `second', `third', ..., through `tenth' return the given element + of the list X. + + - Function: rest x + This function is a synonym for `(cdr X)'. + + - Function: endp x + Common Lisp defines this function to act like `null', but + signalling an error if `x' is neither a `nil' nor a cons cell. + This package simply defines `endp' as a synonym for `null'. + + - Function: list-length x + This function returns the length of list X, exactly like `(length + X)', except that if X is a circular list (where the cdr-chain + forms a loop rather than terminating with `nil'), this function + returns `nil'. (The regular `length' function would get stuck if + given a circular list.) + + - Function: last x &optional n + This function returns the last cons, or the Nth-to-last cons, of + the list X. If N is omitted it defaults to 1. The "last cons" + means the first cons cell of the list whose `cdr' is not another + cons cell. (For normal lists, the `cdr' of the last cons will be + `nil'.) This function returns `nil' if X is `nil' or shorter than + N. Note that the last _element_ of the list is `(car (last X))'. + + - Function: butlast x &optional n + This function returns the list X with the last element, or the + last N elements, removed. If N is greater than zero it makes a + copy of the list so as not to damage the original list. In + general, `(append (butlast X N) (last X N))' will return a list + equal to X. + + - Function: nbutlast x &optional n + This is a version of `butlast' that works by destructively + modifying the `cdr' of the appropriate element, rather than making + a copy of the list. + + - Function: list* arg &rest others + This function constructs a list of its arguments. The final + argument becomes the `cdr' of the last cell constructed. Thus, + `(list* A B C)' is equivalent to `(cons A (cons B C))', and + `(list* A B nil)' is equivalent to `(list A B)'. + + (Note that this function really is called `list*' in Common Lisp; + it is not a name invented for this package like `member*' or + `defun*'.) + + - Function: ldiff list sublist + If SUBLIST is a sublist of LIST, i.e., is `eq' to one of the cons + cells of LIST, then this function returns a copy of the part of + LIST up to but not including SUBLIST. For example, `(ldiff x + (cddr x))' returns the first two elements of the list `x'. The + result is a copy; the original LIST is not modified. If SUBLIST + is not a sublist of LIST, a copy of the entire LIST is returned. + + - Function: copy-list list + This function returns a copy of the list LIST. It copies dotted + lists like `(1 2 . 3)' correctly. + + - Function: copy-tree x &optional vecp + This function returns a copy of the tree of cons cells X. Unlike + `copy-sequence' (and its alias `copy-list'), which copies only + along the `cdr' direction, this function copies (recursively) + along both the `car' and the `cdr' directions. If X is not a cons + cell, the function simply returns X unchanged. If the optional + VECP argument is true, this function copies vectors (recursively) + as well as cons cells. + + - Function: tree-equal x y &key :test :test-not :key + This function compares two trees of cons cells. If X and Y are + both cons cells, their `car's and `cdr's are compared recursively. + If neither X nor Y is a cons cell, they are compared by `eql', or + according to the specified test. The `:key' function, if + specified, is applied to the elements of both trees. *Note + Sequences::. + + +File: cl.info, Node: Substitution of Expressions, Next: Lists as Sets, Prev: List Functions, Up: Lists + +Substitution of Expressions +=========================== + +These functions substitute elements throughout a tree of cons cells. +(*Note Sequence Functions::, for the `substitute' function, which works +on just the top-level elements of a list.) + + - Function: subst new old tree &key :test :test-not :key + This function substitutes occurrences of OLD with NEW in TREE, a + tree of cons cells. It returns a substituted tree, which will be + a copy except that it may share storage with the argument TREE in + parts where no substitutions occurred. The original TREE is not + modified. This function recurses on, and compares against OLD, + both `car's and `cdr's of the component cons cells. If OLD is + itself a cons cell, then matching cells in the tree are + substituted as usual without recursively substituting in that + cell. Comparisons with OLD are done according to the specified + test (`eql' by default). The `:key' function is applied to the + elements of the tree but not to OLD. + + - Function: nsubst new old tree &key :test :test-not :key + This function is like `subst', except that it works by destructive + modification (by `setcar' or `setcdr') rather than copying. + + The `subst-if', `subst-if-not', `nsubst-if', and `nsubst-if-not' +functions are defined similarly. + + - Function: sublis alist tree &key :test :test-not :key + This function is like `subst', except that it takes an association + list ALIST of OLD-NEW pairs. Each element of the tree (after + applying the `:key' function, if any), is compared with the `car's + of ALIST; if it matches, it is replaced by the corresponding `cdr'. + + - Function: nsublis alist tree &key :test :test-not :key + This is a destructive version of `sublis'. + + +File: cl.info, Node: Lists as Sets, Next: Association Lists, Prev: Substitution of Expressions, Up: Lists + +Lists as Sets +============= + +These functions perform operations on lists which represent sets of +elements. + + - Function: member item list + This MacLisp-compatible function searches LIST for an element + which is `equal' to ITEM. The `member' function is built-in to + Emacs 19; this package defines it equivalently in Emacs 18. See + the following function for a Common-Lisp compatible version. + + - Function: member* item list &key :test :test-not :key + This function searches LIST for an element matching ITEM. If a + match is found, it returns the cons cell whose `car' was the + matching element. Otherwise, it returns `nil'. Elements are + compared by `eql' by default; you can use the `:test', + `:test-not', and `:key' arguments to modify this behavior. *Note + Sequences::. + + Note that this function's name is suffixed by `*' to avoid the + incompatible `member' function defined in Emacs 19. (That + function uses `equal' for comparisons; it is equivalent to + `(member* ITEM LIST :test 'equal)'.) + + The `member-if' and `member-if-not' functions analogously search for +elements which satisfy a given predicate. + + - Function: tailp sublist list + This function returns `t' if SUBLIST is a sublist of LIST, i.e., + if SUBLIST is `eql' to LIST or to any of its `cdr's. + + - Function: adjoin item list &key :test :test-not :key + This function conses ITEM onto the front of LIST, like `(cons ITEM + LIST)', but only if ITEM is not already present on the list (as + determined by `member*'). If a `:key' argument is specified, it + is applied to ITEM as well as to the elements of LIST during the + search, on the reasoning that ITEM is "about" to become part of + the list. + + - Function: union list1 list2 &key :test :test-not :key + This function combines two lists which represent sets of items, + returning a list that represents the union of those two sets. The + result list will contain all items which appear in LIST1 or LIST2, + and no others. If an item appears in both LIST1 and LIST2 it will + be copied only once. If an item is duplicated in LIST1 or LIST2, + it is undefined whether or not that duplication will survive in the + result list. The order of elements in the result list is also + undefined. + + - Function: nunion list1 list2 &key :test :test-not :key + This is a destructive version of `union'; rather than copying, it + tries to reuse the storage of the argument lists if possible. + + - Function: intersection list1 list2 &key :test :test-not :key + This function computes the intersection of the sets represented by + LIST1 and LIST2. It returns the list of items which appear in + both LIST1 and LIST2. + + - Function: nintersection list1 list2 &key :test :test-not :key + This is a destructive version of `intersection'. It tries to + reuse storage of LIST1 rather than copying. It does _not_ reuse + the storage of LIST2. + + - Function: set-difference list1 list2 &key :test :test-not :key + This function computes the "set difference" of LIST1 and LIST2, + i.e., the set of elements that appear in LIST1 but _not_ in LIST2. + + - Function: nset-difference list1 list2 &key :test :test-not :key + This is a destructive `set-difference', which will try to reuse + LIST1 if possible. + + - Function: set-exclusive-or list1 list2 &key :test :test-not :key + This function computes the "set exclusive or" of LIST1 and LIST2, + i.e., the set of elements that appear in exactly one of LIST1 and + LIST2. + + - Function: nset-exclusive-or list1 list2 &key :test :test-not :key + This is a destructive `set-exclusive-or', which will try to reuse + LIST1 and LIST2 if possible. + + - Function: subsetp list1 list2 &key :test :test-not :key + This function checks whether LIST1 represents a subset of LIST2, + i.e., whether every element of LIST1 also appears in LIST2. + + +File: cl.info, Node: Association Lists, Prev: Lists as Sets, Up: Lists + +Association Lists +================= + +An "association list" is a list representing a mapping from one set of +values to another; any list whose elements are cons cells is an +association list. + + - Function: assoc* item a-list &key :test :test-not :key + This function searches the association list A-LIST for an element + whose `car' matches (in the sense of `:test', `:test-not', and + `:key', or by comparison with `eql') a given ITEM. It returns the + matching element, if any, otherwise `nil'. It ignores elements of + A-LIST which are not cons cells. (This corresponds to the + behavior of `assq' and `assoc' in Emacs Lisp; Common Lisp's + `assoc' ignores `nil's but considers any other non-cons elements + of A-LIST to be an error.) + + - Function: rassoc* item a-list &key :test :test-not :key + This function searches for an element whose `cdr' matches ITEM. + If A-LIST represents a mapping, this applies the inverse of the + mapping to ITEM. + + - Function: rassoc item a-list + This function searches like `rassoc*' with a `:test' argument of + `equal'. It is analogous to Emacs Lisp's standard `assoc' + function, which derives from the MacLisp rather than the Common + Lisp tradition. + + The `assoc-if', `assoc-if-not', `rassoc-if', and `rassoc-if-not' +functions are defined similarly. + + Two simple functions for constructing association lists are: + + - Function: acons key value alist + This is equivalent to `(cons (cons KEY VALUE) ALIST)'. + + - Function: pairlis keys values &optional alist + This is equivalent to `(nconc (mapcar* 'cons KEYS VALUES) ALIST)'. + + +File: cl.info, Node: Hash Tables, Next: Structures, Prev: Lists, Up: Top + +Hash Tables +*********** + +Hash tables are now implemented directly in the C code and documented in +*Note Hash Tables: (lispref)Hash Tables. + + +File: cl.info, Node: Structures, Next: Assertions, Prev: Hash Tables, Up: Top + +Structures +********** + +The Common Lisp "structure" mechanism provides a general way to define +data types similar to C's `struct' types. A structure is a Lisp object +containing some number of "slots", each of which can hold any Lisp data +object. Functions are provided for accessing and setting the slots, +creating or copying structure objects, and recognizing objects of a +particular structure type. + + In true Common Lisp, each structure type is a new type distinct from +all existing Lisp types. Since the underlying Emacs Lisp system +provides no way to create new distinct types, this package implements +structures as vectors (or lists upon request) with a special "tag" +symbol to identify them. + + - Special Form: defstruct name slots... + The `defstruct' form defines a new structure type called NAME, + with the specified SLOTS. (The SLOTS may begin with a string + which documents the structure type.) In the simplest case, NAME + and each of the SLOTS are symbols. For example, + + (defstruct person name age sex) + + defines a struct type called `person' which contains three slots. + Given a `person' object P, you can access those slots by calling + `(person-name P)', `(person-age P)', and `(person-sex P)'. You + can also change these slots by using `setf' on any of these place + forms: + + (incf (person-age birthday-boy)) + + You can create a new `person' by calling `make-person', which + takes keyword arguments `:name', `:age', and `:sex' to specify the + initial values of these slots in the new object. (Omitting any of + these arguments leaves the corresponding slot "undefined," + according to the Common Lisp standard; in Emacs Lisp, such + uninitialized slots are filled with `nil'.) + + Given a `person', `(copy-person P)' makes a new object of the same + type whose slots are `eq' to those of P. + + Given any Lisp object X, `(person-p X)' returns true if X looks + like a `person', false otherwise. (Again, in Common Lisp this + predicate would be exact; in Emacs Lisp the best it can do is + verify that X is a vector of the correct length which starts with + the correct tag symbol.) + + Accessors like `person-name' normally check their arguments + (effectively using `person-p') and signal an error if the argument + is the wrong type. This check is affected by `(optimize (safety + ...))' declarations. Safety level 1, the default, uses a somewhat + optimized check that will detect all incorrect arguments, but may + use an uninformative error message (e.g., "expected a vector" + instead of "expected a `person'"). Safety level 0 omits all + checks except as provided by the underlying `aref' call; safety + levels 2 and 3 do rigorous checking that will always print a + descriptive error message for incorrect inputs. *Note + Declarations::. + + (setq dave (make-person :name "Dave" :sex 'male)) + => [cl-struct-person "Dave" nil male] + (setq other (copy-person dave)) + => [cl-struct-person "Dave" nil male] + (eq dave other) + => nil + (eq (person-name dave) (person-name other)) + => t + (person-p dave) + => t + (person-p [1 2 3 4]) + => nil + (person-p "Bogus") + => nil + (person-p '[cl-struct-person counterfeit person object]) + => t + + In general, NAME is either a name symbol or a list of a name + symbol followed by any number of "struct options"; each SLOT is + either a slot symbol or a list of the form `(SLOT-NAME + DEFAULT-VALUE SLOT-OPTIONS...)'. The DEFAULT-VALUE is a Lisp form + which is evaluated any time an instance of the structure type is + created without specifying that slot's value. + + Common Lisp defines several slot options, but the only one + implemented in this package is `:read-only'. A non-`nil' value + for this option means the slot should not be `setf'-able; the + slot's value is determined when the object is created and does not + change afterward. + + (defstruct person + (name nil :read-only t) + age + (sex 'unknown)) + + Any slot options other than `:read-only' are ignored. + + For obscure historical reasons, structure options take a different + form than slot options. A structure option is either a keyword + symbol, or a list beginning with a keyword symbol possibly followed + by arguments. (By contrast, slot options are key-value pairs not + enclosed in lists.) + + (defstruct (person (:constructor create-person) + (:type list) + :named) + name age sex) + + The following structure options are recognized. + + `:conc-name' + The argument is a symbol whose print name is used as the + prefix for the names of slot accessor functions. The default + is the name of the struct type followed by a hyphen. The + option `(:conc-name p-)' would change this prefix to `p-'. + Specifying `nil' as an argument means no prefix, so that the + slot names themselves are used to name the accessor functions. + + `:constructor' + In the simple case, this option takes one argument which is an + alternate name to use for the constructor function. The + default is `make-NAME', e.g., `make-person'. The above + example changes this to `create-person'. Specifying `nil' as + an argument means that no standard constructor should be + generated at all. + + In the full form of this option, the constructor name is + followed by an arbitrary argument list. *Note Program + Structure::, for a description of the format of Common Lisp + argument lists. All options, such as `&rest' and `&key', are + supported. The argument names should match the slot names; + each slot is initialized from the corresponding argument. + Slots whose names do not appear in the argument list are + initialized based on the DEFAULT-VALUE in their slot + descriptor. Also, `&optional' and `&key' arguments which + don't specify defaults take their defaults from the slot + descriptor. It is legal to include arguments which don't + correspond to slot names; these are useful if they are + referred to in the defaults for optional, keyword, or `&aux' + arguments which _do_ correspond to slots. + + You can specify any number of full-format `:constructor' + options on a structure. The default constructor is still + generated as well unless you disable it with a simple-format + `:constructor' option. + + (defstruct + (person + (:constructor nil) ; no default constructor + (:constructor new-person (name sex &optional (age 0))) + (:constructor new-hound (&key (name "Rover") + (dog-years 0) + &aux (age (* 7 dog-years)) + (sex 'canine)))) + name age sex) + + The first constructor here takes its arguments positionally + rather than by keyword. (In official Common Lisp + terminology, constructors that work By Order of Arguments + instead of by keyword are called "BOA constructors." No, I'm + not making this up.) For example, `(new-person "Jane" + 'female)' generates a person whose slots are `"Jane"', 0, and + `female', respectively. + + The second constructor takes two keyword arguments, `:name', + which initializes the `name' slot and defaults to `"Rover"', + and `:dog-years', which does not itself correspond to a slot + but which is used to initialize the `age' slot. The `sex' + slot is forced to the symbol `canine' with no syntax for + overriding it. + + `:copier' + The argument is an alternate name for the copier function for + this type. The default is `copy-NAME'. `nil' means not to + generate a copier function. (In this implementation, all + copier functions are simply synonyms for `copy-sequence'.) + + `:predicate' + The argument is an alternate name for the predicate which + recognizes objects of this type. The default is `NAME-p'. + `nil' means not to generate a predicate function. (If the + `:type' option is used without the `:named' option, no + predicate is ever generated.) + + In true Common Lisp, `typep' is always able to recognize a + structure object even if `:predicate' was used. In this + package, `typep' simply looks for a function called + `TYPENAME-p', so it will work for structure types only if + they used the default predicate name. + + `:include' + This option implements a very limited form of C++-style + inheritance. The argument is the name of another structure + type previously created with `defstruct'. The effect is to + cause the new structure type to inherit all of the included + structure's slots (plus, of course, any new slots described + by this struct's slot descriptors). The new structure is + considered a "specialization" of the included one. In fact, + the predicate and slot accessors for the included type will + also accept objects of the new type. + + If there are extra arguments to the `:include' option after + the included-structure name, these options are treated as + replacement slot descriptors for slots in the included + structure, possibly with modified default values. Borrowing + an example from Steele: + + (defstruct person name (age 0) sex) + => person + (defstruct (astronaut (:include person (age 45))) + helmet-size + (favorite-beverage 'tang)) + => astronaut + + (setq joe (make-person :name "Joe")) + => [cl-struct-person "Joe" 0 nil] + (setq buzz (make-astronaut :name "Buzz")) + => [cl-struct-astronaut "Buzz" 45 nil nil tang] + + (list (person-p joe) (person-p buzz)) + => (t t) + (list (astronaut-p joe) (astronaut-p buzz)) + => (nil t) + + (person-name buzz) + => "Buzz" + (astronaut-name joe) + => error: "astronaut-name accessing a non-astronaut" + + Thus, if `astronaut' is a specialization of `person', then + every `astronaut' is also a `person' (but not the other way + around). Every `astronaut' includes all the slots of a + `person', plus extra slots that are specific to astronauts. + Operations that work on people (like `person-name') work on + astronauts just like other people. + + `:print-function' + In full Common Lisp, this option allows you to specify a + function which is called to print an instance of the + structure type. The Emacs Lisp system offers no hooks into + the Lisp printer which would allow for such a feature, so + this package simply ignores `:print-function'. + + `:type' + The argument should be one of the symbols `vector' or `list'. + This tells which underlying Lisp data type should be used to + implement the new structure type. Vectors are used by + default, but `(:type list)' will cause structure objects to + be stored as lists instead. + + The vector representation for structure objects has the + advantage that all structure slots can be accessed quickly, + although creating vectors is a bit slower in Emacs Lisp. + Lists are easier to create, but take a relatively long time + accessing the later slots. + + `:named' + This option, which takes no arguments, causes a + characteristic "tag" symbol to be stored at the front of the + structure object. Using `:type' without also using `:named' + will result in a structure type stored as plain vectors or + lists with no identifying features. + + The default, if you don't specify `:type' explicitly, is to + use named vectors. Therefore, `:named' is only useful in + conjunction with `:type'. + + (defstruct (person1) name age sex) + (defstruct (person2 (:type list) :named) name age sex) + (defstruct (person3 (:type list)) name age sex) + + (setq p1 (make-person1)) + => [cl-struct-person1 nil nil nil] + (setq p2 (make-person2)) + => (person2 nil nil nil) + (setq p3 (make-person3)) + => (nil nil nil) + + (person1-p p1) + => t + (person2-p p2) + => t + (person3-p p3) + => error: function person3-p undefined + + Since unnamed structures don't have tags, `defstruct' is not + able to make a useful predicate for recognizing them. Also, + accessors like `person3-name' will be generated but they will + not be able to do any type checking. The `person3-name' + function, for example, will simply be a synonym for `car' in + this case. By contrast, `person2-name' is able to verify + that its argument is indeed a `person2' object before + proceeding. + + `:initial-offset' + The argument must be a nonnegative integer. It specifies a + number of slots to be left "empty" at the front of the + structure. If the structure is named, the tag appears at the + specified position in the list or vector; otherwise, the first + slot appears at that position. Earlier positions are filled + with `nil' by the constructors and ignored otherwise. If the + type `:include's another type, then `:initial-offset' + specifies a number of slots to be skipped between the last + slot of the included type and the first new slot. + + Except as noted, the `defstruct' facility of this package is +entirely compatible with that of Common Lisp. + + +File: cl.info, Node: Assertions, Next: Efficiency Concerns, Prev: Structures, Up: Top + +Assertions and Errors +********************* + +This section describes two macros that test "assertions", i.e., +conditions which must be true if the program is operating correctly. +Assertions never add to the behavior of a Lisp program; they simply +make "sanity checks" to make sure everything is as it should be. + + If the optimization property `speed' has been set to 3, and `safety' +is less than 3, then the byte-compiler will optimize away the following +assertions. Because assertions might be optimized away, it is a bad +idea for them to include side-effects. + + - Special Form: assert test-form [show-args string args...] + This form verifies that TEST-FORM is true (i.e., evaluates to a + non-`nil' value). If so, it returns `nil'. If the test is not + satisfied, `assert' signals an error. + + A default error message will be supplied which includes TEST-FORM. + You can specify a different error message by including a STRING + argument plus optional extra arguments. Those arguments are simply + passed to `error' to signal the error. + + If the optional second argument SHOW-ARGS is `t' instead of `nil', + then the error message (with or without STRING) will also include + all non-constant arguments of the top-level FORM. For example: + + (assert (> x 10) t "x is too small: %d") + + This usage of SHOW-ARGS is a change to Common Lisp. In true + Common Lisp, the second argument gives a list of PLACES which can + be `setf''d by the user before continuing from the error. + + - Special Form: check-type place type &optional string + This form verifies that PLACE evaluates to a value of type TYPE. + If so, it returns `nil'. If not, `check-type' signals a + continuable `wrong-type-argument' error. The default error + message lists the erroneous value along with TYPE and PLACE + themselves. If STRING is specified, it is included in the error + message in place of TYPE. For example: + + (check-type x (integer 1 *) "a positive integer") + + *Note Type Predicates::, for a description of the type specifiers + that may be used for TYPE. + + Note that as in Common Lisp, the first argument to `check-type' + should be a PLACE suitable for use by `setf', because `check-type' + signals a continuable error that allows the user to modify PLACE, + most simply by returning a value from the debugger. + + The following error-related macro is also defined: + + - Special Form: ignore-errors forms... + This executes FORMS exactly like a `progn', except that errors are + ignored during the FORMS. More precisely, if an error is + signalled then `ignore-errors' immediately aborts execution of the + FORMS and returns `nil'. If the FORMS complete successfully, + `ignore-errors' returns the result of the last FORM. + + +File: cl.info, Node: Efficiency Concerns, Next: Common Lisp Compatibility, Prev: Assertions, Up: Top + +Efficiency Concerns +******************* + +Macros +====== + +Many of the advanced features of this package, such as `defun*', +`loop', and `setf', are implemented as Lisp macros. In byte-compiled +code, these complex notations will be expanded into equivalent Lisp +code which is simple and efficient. For example, the forms + + (incf i n) + (push x (car p)) + +are expanded at compile-time to the Lisp forms + + (setq i (+ i n)) + (setcar p (cons x (car p))) + +which are the most efficient ways of doing these respective operations +in Lisp. Thus, there is no performance penalty for using the more +readable `incf' and `push' forms in your compiled code. + + _Interpreted_ code, on the other hand, must expand these macros +every time they are executed. For this reason it is strongly +recommended that code making heavy use of macros be compiled. (The +features labelled "Special Form" instead of "Function" in this manual +are macros.) A loop using `incf' a hundred times will execute +considerably faster if compiled, and will also garbage-collect less +because the macro expansion will not have to be generated, used, and +thrown away a hundred times. + + You can find out how a macro expands by using the `cl-prettyexpand' +function. + + - Function: cl-prettyexpand form &optional full + This function takes a single Lisp form as an argument and inserts + a nicely formatted copy of it in the current buffer (which must be + in Lisp mode so that indentation works properly). It also expands + all Lisp macros which appear in the form. The easiest way to use + this function is to go to the `*scratch*' buffer and type, say, + + (cl-prettyexpand '(loop for x below 10 collect x)) + + and type `C-x C-e' immediately after the closing parenthesis; the + expansion + + (block nil + (let* ((x 0) + (G1004 nil)) + (while (< x 10) + (setq G1004 (cons x G1004)) + (setq x (+ x 1))) + (nreverse G1004))) + + will be inserted into the buffer. (The `block' macro is expanded + differently in the interpreter and compiler, so `cl-prettyexpand' + just leaves it alone. The temporary variable `G1004' was created + by `gensym'.) + + If the optional argument FULL is true, then _all_ macros are + expanded, including `block', `eval-when', and compiler macros. + Expansion is done as if FORM were a top-level form in a file being + compiled. For example, + + (cl-prettyexpand '(pushnew 'x list)) + -| (setq list (adjoin 'x list)) + (cl-prettyexpand '(pushnew 'x list) t) + -| (setq list (if (memq 'x list) list (cons 'x list))) + (cl-prettyexpand '(caddr (member* 'a list)) t) + -| (car (cdr (cdr (memq 'a list)))) + + Note that `adjoin', `caddr', and `member*' all have built-in + compiler macros to optimize them in common cases. + + +Error Checking +============== + +Common Lisp compliance has in general not been sacrificed for the sake +of efficiency. A few exceptions have been made for cases where +substantial gains were possible at the expense of marginal +incompatibility. One example is the use of `memq' (which is treated +very efficiently by the byte-compiler) to scan for keyword arguments; +this can become confused in rare cases when keyword symbols are used as +both keywords and data values at once. This is extremely unlikely to +occur in practical code, and the use of `memq' allows functions with +keyword arguments to be nearly as fast as functions that use +`&optional' arguments. + + The Common Lisp standard (as embodied in Steele's book) uses the +phrase "it is an error if" to indicate a situation which is not +supposed to arise in complying programs; implementations are strongly +encouraged but not required to signal an error in these situations. +This package sometimes omits such error checking in the interest of +compactness and efficiency. For example, `do' variable specifiers are +supposed to be lists of one, two, or three forms; extra forms are +ignored by this package rather than signalling a syntax error. The +`endp' function is simply a synonym for `null' in this package. +Functions taking keyword arguments will accept an odd number of +arguments, treating the trailing keyword as if it were followed by the +value `nil'. + + Argument lists (as processed by `defun*' and friends) _are_ checked +rigorously except for the minor point just mentioned; in particular, +keyword arguments are checked for validity, and `&allow-other-keys' and +`:allow-other-keys' are fully implemented. Keyword validity checking +is slightly time consuming (though not too bad in byte-compiled code); +you can use `&allow-other-keys' to omit this check. Functions defined +in this package such as `find' and `member*' do check their keyword +arguments for validity. + + +Optimizing Compiler +=================== + +The byte-compiler that comes with Emacs 18 normally fails to expand +macros that appear in top-level positions in the file (i.e., outside of +`defun's or other enclosing forms). This would have disastrous +consequences to programs that used such top-level macros as `defun*', +`eval-when', and `defstruct'. To work around this problem, the "CL" +package patches the Emacs 18 compiler to expand top-level macros. This +patch will apply to your own macros, too, if they are used in a +top-level context. The patch will not harm versions of the Emacs 18 +compiler which have already had a similar patch applied, nor will it +affect the optimizing Emacs 19 byte-compiler written by Jamie Zawinski +and Hallvard Furuseth. The patch is applied to the byte compiler's +code in Emacs' memory, _not_ to the `bytecomp.elc' file stored on disk. + + The Emacs 19 compiler (for Emacs 18) is available from various Emacs +Lisp archive sites such as `archive.cis.ohio-state.edu'. Its use is +highly recommended; many of the Common Lisp macros emit code which can +be improved by optimization. In particular, `block's (whether explicit +or implicit in constructs like `defun*' and `loop') carry a fair +run-time penalty; the optimizing compiler removes `block's which are +not actually referenced by `return' or `return-from' inside the block. + + +File: cl.info, Node: Common Lisp Compatibility, Next: Old CL Compatibility, Prev: Efficiency Concerns, Up: Top + +Common Lisp Compatibility +************************* + +Following is a list of all known incompatibilities between this package +and Common Lisp as documented in Steele (2nd edition). + + Certain function names, such as `member', `assoc', and `floor', were +already taken by (incompatible) Emacs Lisp functions; this package +appends `*' to the names of its Common Lisp versions of these functions. + + The word `defun*' is required instead of `defun' in order to use +extended Common Lisp argument lists in a function. Likewise, +`defmacro*' and `function*' are versions of those forms which +understand full-featured argument lists. The `&whole' keyword does not +work in `defmacro' argument lists (except inside recursive argument +lists). + + In order to allow an efficient implementation, keyword arguments use +a slightly cheesy parser which may be confused if a keyword symbol is +passed as the _value_ of another keyword argument. (Specifically, +`(memq :KEYWORD REST-OF-ARGUMENTS)' is used to scan for `:KEYWORD' +among the supplied keyword arguments.) + + The `eql' and `equal' predicates do not distinguish between IEEE +floating-point plus and minus zero. The `equalp' predicate has several +differences with Common Lisp; *note Predicates::. + + The `setf' mechanism is entirely compatible, except that +setf-methods return a list of five values rather than five values +directly. Also, the new "`setf' function" concept (typified by `(defun +(setf foo) ...)') is not implemented. + + The `do-all-symbols' form is the same as `do-symbols' with no +OBARRAY argument. In Common Lisp, this form would iterate over all +symbols in all packages. Since Emacs obarrays are not a first-class +package mechanism, there is no way for `do-all-symbols' to locate any +but the default obarray. + + The `loop' macro is complete except that `loop-finish' and type +specifiers are unimplemented. + + The multiple-value return facility treats lists as multiple values, +since Emacs Lisp cannot support multiple return values directly. The +macros will be compatible with Common Lisp if `values' or `values-list' +is always used to return to a `multiple-value-bind' or other +multiple-value receiver; if `values' is used without +`multiple-value-...' or vice-versa the effect will be different from +Common Lisp. + + Many Common Lisp declarations are ignored, and others match the +Common Lisp standard in concept but not in detail. For example, local +`special' declarations, which are purely advisory in Emacs Lisp, do not +rigorously obey the scoping rules set down in Steele's book. + + The variable `*gensym-counter*' starts out with a pseudo-random +value rather than with zero. This is to cope with the fact that +generated symbols become interned when they are written to and loaded +back from a file. + + The `defstruct' facility is compatible, except that structures are +of type `:type vector :named' by default rather than some special, +distinct type. Also, the `:type' slot option is ignored. + + The second argument of `check-type' is treated differently. + + +File: cl.info, Node: Old CL Compatibility, Next: Porting Common Lisp, Prev: Common Lisp Compatibility, Up: Top + +Old CL Compatibility +******************** + +Following is a list of all known incompatibilities between this package +and the older Quiroz `cl.el' package. + + This package's emulation of multiple return values in functions is +incompatible with that of the older package. That package attempted to +come as close as possible to true Common Lisp multiple return values; +unfortunately, it could not be 100% reliable and so was prone to +occasional surprises if used freely. This package uses a simpler +method, namely replacing multiple values with lists of values, which is +more predictable though more noticeably different from Common Lisp. + + The `defkeyword' form and `keywordp' function are not implemented in +this package. + + The `member', `floor', `ceiling', `truncate', `round', `mod', and +`rem' functions are suffixed by `*' in this package to avoid collision +with existing functions in Emacs 18 or Emacs 19. The older package +simply redefined these functions, overwriting the built-in meanings and +causing serious portability problems with Emacs 19. (Some more recent +versions of the Quiroz package changed the names to `cl-member', etc.; +this package defines the latter names as aliases for `member*', etc.) + + Certain functions in the old package which were buggy or inconsistent +with the Common Lisp standard are incompatible with the conforming +versions in this package. For example, `eql' and `member' were +synonyms for `eq' and `memq' in that package, `setf' failed to preserve +correct order of evaluation of its arguments, etc. + + Finally, unlike the older package, this package is careful to prefix +all of its internal names with `cl-'. Except for a few functions which +are explicitly defined as additional features (such as `floatp-safe' +and `letf'), this package does not export any non-`cl-' symbols which +are not also part of Common Lisp. + + +The `cl-compat' package +======================= + +The "CL" package includes emulations of some features of the old +`cl.el', in the form of a compatibility package `cl-compat'. To use +it, put `(require 'cl-compat)' in your program. + + The old package defined a number of internal routines without `cl-' +prefixes or other annotations. Call to these routines may have crept +into existing Lisp code. `cl-compat' provides emulations of the +following internal routines: `pair-with-newsyms', `zip-lists', +`unzip-lists', `reassemble-arglists', `duplicate-symbols-p', +`safe-idiv'. + + Some `setf' forms translated into calls to internal functions that +user code might call directly. The functions `setnth', `setnthcdr', +and `setelt' fall in this category; they are defined by `cl-compat', +but the best fix is to change to use `setf' properly. + + The `cl-compat' file defines the keyword functions `keywordp', +`keyword-of', and `defkeyword', which are not defined by the new "CL" +package because the use of keywords as data is discouraged. + + The `build-klist' mechanism for parsing keyword arguments is +emulated by `cl-compat'; the `with-keyword-args' macro is not, however, +and in any case it's best to change to use the more natural keyword +argument processing offered by `defun*'. + + Multiple return values are treated differently by the two Common +Lisp packages. The old package's method was more compatible with true +Common Lisp, though it used heuristics that caused it to report +spurious multiple return values in certain cases. The `cl-compat' +package defines a set of multiple-value macros that are compatible with +the old CL package; again, they are heuristic in nature, but they are +guaranteed to work in any case where the old package's macros worked. +To avoid name collision with the "official" multiple-value facilities, +the ones in `cl-compat' have capitalized names: `Values', +`Values-list', `Multiple-value-bind', etc. + + The functions `cl-floor', `cl-ceiling', `cl-truncate', and +`cl-round' are defined by `cl-compat' to use the old-style +multiple-value mechanism, just as they did in the old package. The +newer `floor*' and friends return their two results in a list rather +than as multiple values. Note that older versions of the old package +used the unadorned names `floor', `ceiling', etc.; `cl-compat' cannot +use these names because they conflict with Emacs 19 built-ins. + + +File: cl.info, Node: Porting Common Lisp, Next: Function Index, Prev: Old CL Compatibility, Up: Top + +Porting Common Lisp +******************* + +This package is meant to be used as an extension to Emacs Lisp, not as +an Emacs implementation of true Common Lisp. Some of the remaining +differences between Emacs Lisp and Common Lisp make it difficult to +port large Common Lisp applications to Emacs. For one, some of the +features in this package are not fully compliant with ANSI or Steele; +*note Common Lisp Compatibility::. But there are also quite a few +features that this package does not provide at all. Here are some +major omissions that you will want watch out for when bringing Common +Lisp code into Emacs. + + * Case-insensitivity. Symbols in Common Lisp are case-insensitive + by default. Some programs refer to a function or variable as + `foo' in one place and `Foo' or `FOO' in another. Emacs Lisp will + treat these as three distinct symbols. + + Some Common Lisp code is written in all upper-case. While Emacs + is happy to let the program's own functions and variables use this + convention, calls to Lisp builtins like `if' and `defun' will have + to be changed to lower-case. + + * Lexical scoping. In Common Lisp, function arguments and `let' + bindings apply only to references physically within their bodies + (or within macro expansions in their bodies). Emacs Lisp, by + contrast, uses "dynamic scoping" wherein a binding to a variable + is visible even inside functions called from the body. + + Variables in Common Lisp can be made dynamically scoped by + declaring them `special' or using `defvar'. In Emacs Lisp it is + as if all variables were declared `special'. + + Often you can use code that was written for lexical scoping even + in a dynamically scoped Lisp, but not always. Here is an example + of a Common Lisp code fragment that would fail in Emacs Lisp: + + (defun map-odd-elements (func list) + (loop for x in list + for flag = t then (not flag) + collect (if flag x (funcall func x)))) + + (defun add-odd-elements (list x) + (map-odd-elements (function (lambda (a) (+ a x))) list)) + + In Common Lisp, the two functions' usages of `x' are completely + independent. In Emacs Lisp, the binding to `x' made by + `add-odd-elements' will have been hidden by the binding in + `map-odd-elements' by the time the `(+ a x)' function is called. + + (This package avoids such problems in its own mapping functions by + using names like `cl-x' instead of `x' internally; as long as you + don't use the `cl-' prefix for your own variables no collision can + occur.) + + *Note Lexical Bindings::, for a description of the `lexical-let' + form which establishes a Common Lisp-style lexical binding, and + some examples of how it differs from Emacs' regular `let'. + + * Common Lisp allows the shorthand `#'x' to stand for `(function + x)', just as `'x' stands for `(quote x)'. In Common Lisp, one + traditionally uses `#'' notation when referring to the name of a + function. In Emacs Lisp, it works just as well to use a regular + quote: + + (loop for x in y by #'cddr collect (mapcar #'plusp x)) ; Common Lisp + (loop for x in y by 'cddr collect (mapcar 'plusp x)) ; Emacs Lisp + + When `#'' introduces a `lambda' form, it is best to write out + `(function ...)' longhand in Emacs Lisp. You can use a regular + quote, but then the byte-compiler won't know that the `lambda' + expression is code that can be compiled. + + (mapcar #'(lambda (x) (* x 2)) list) ; Common Lisp + (mapcar (function (lambda (x) (* x 2))) list) ; Emacs Lisp + + XEmacs supports `#'' notation starting with version 19.8. + + * Reader macros. Common Lisp includes a second type of macro that + works at the level of individual characters. For example, Common + Lisp implements the quote notation by a reader macro called `'', + whereas Emacs Lisp's parser just treats quote as a special case. + Some Lisp packages use reader macros to create special syntaxes + for themselves, which the Emacs parser is incapable of reading. + + * Other syntactic features. Common Lisp provides a number of + notations beginning with `#' that the Emacs Lisp parser won't + understand. For example, `#| ... |#' is an alternate comment + notation, and `#+lucid (foo)' tells the parser to ignore the + `(foo)' except in Lucid Common Lisp. + + The number prefixes `#b', `#o', and `#x', however, are supported + by the Emacs Lisp parser to represent numbers in binary, octal, + and hexadecimal notation (or radix), just like in Common Lisp. + + * Packages. In Common Lisp, symbols are divided into "packages". + Symbols that are Lisp built-ins are typically stored in one + package; symbols that are vendor extensions are put in another, + and each application program would have a package for its own + symbols. Certain symbols are "exported" by a package and others + are internal; certain packages "use" or import the exported symbols + of other packages. To access symbols that would not normally be + visible due to this importing and exporting, Common Lisp provides + a syntax like `package:symbol' or `package::symbol'. + + Emacs Lisp has a single namespace for all interned symbols, and + then uses a naming convention of putting a prefix like `cl-' in + front of the name. Some Emacs packages adopt the Common Lisp-like + convention of using `cl:' or `cl::' as the prefix. However, the + Emacs parser does not understand colons and just treats them as + part of the symbol name. Thus, while `mapcar' and `lisp:mapcar' + may refer to the same symbol in Common Lisp, they are totally + distinct in Emacs Lisp. Common Lisp programs which refer to a + symbol by the full name sometimes and the short name other times + will not port cleanly to Emacs. + + Emacs Lisp does have a concept of "obarrays," which are + package-like collections of symbols, but this feature is not + strong enough to be used as a true package mechanism. + + * Keywords. The notation `:test-not' in Common Lisp really is a + shorthand for `keyword:test-not'; keywords are just symbols in a + built-in `keyword' package with the special property that all its + symbols are automatically self-evaluating. Common Lisp programs + often use keywords liberally to avoid having to use quotes. + + In Emacs Lisp a keyword is just a symbol whose name begins with a + colon; since the Emacs parser does not treat them specially, they + have to be explicitly made self-evaluating by a statement like + `(setq :test-not ':test-not)'. This package arranges to execute + such a statement whenever `defun*' or some other form sees a + keyword being used as an argument. Common Lisp code that assumes + that a symbol `:mumble' will be self-evaluating even though it was + never introduced by a `defun*' will have to be fixed. + + * The `format' function is quite different between Common Lisp and + Emacs Lisp. It takes an additional "destination" argument before + the format string. A destination of `nil' means to format to a + string as in Emacs Lisp; a destination of `t' means to write to + the terminal (similar to `message' in Emacs). Also, format + control strings are utterly different; `~' is used instead of `%' + to introduce format codes, and the set of available codes is much + richer. There are no notations like `\n' for string literals; + instead, `format' is used with the "newline" format code, `~%'. + More advanced formatting codes provide such features as paragraph + filling, case conversion, and even loops and conditionals. + + While it would have been possible to implement most of Common Lisp + `format' in this package (under the name `format*', of course), it + was not deemed worthwhile. It would have required a huge amount + of code to implement even a decent subset of `format*', yet the + functionality it would provide over Emacs Lisp's `format' would + rarely be useful. + + * Vector constants use square brackets in Emacs Lisp, but `#(a b c)' + notation in Common Lisp. To further complicate matters, Emacs 19 + introduces its own `#(' notation for something entirely + different--strings with properties. + + * Characters are distinct from integers in Common Lisp. The + notation for character constants is also different: `#\A' instead + of `?A'. Also, `string=' and `string-equal' are synonyms in Emacs + Lisp whereas the latter is case-insensitive in Common Lisp. + + * Data types. Some Common Lisp data types do not exist in Emacs + Lisp. Rational numbers and complex numbers are not present, nor + are large integers (all integers are "fixnums"). All arrays are + one-dimensional. There are no readtables or pathnames; streams + are a set of existing data types rather than a new data type of + their own. Hash tables, random-states, structures, and packages + (obarrays) are built from Lisp vectors or lists rather than being + distinct types. + + * The Common Lisp Object System (CLOS) is not implemented, nor is + the Common Lisp Condition System. + + * Common Lisp features that are completely redundant with Emacs Lisp + features of a different name generally have not been implemented. + For example, Common Lisp writes `defconstant' where Emacs Lisp + uses `defconst'. Similarly, `make-list' takes its arguments in + different ways in the two Lisps but does exactly the same thing, + so this package has not bothered to implement a Common Lisp-style + `make-list'. + + * A few more notable Common Lisp features not included in this + package: `compiler-let', `tagbody', `prog', `ldb/dpb', + `parse-integer', `cerror'. + + * Recursion. While recursion works in Emacs Lisp just like it does + in Common Lisp, various details of the Emacs Lisp system and + compiler make recursion much less efficient than it is in most + Lisps. Some schools of thought prefer to use recursion in Lisp + over other techniques; they would sum a list of numbers using + something like + + (defun sum-list (list) + (if list + (+ (car list) (sum-list (cdr list))) + 0)) + + where a more iteratively-minded programmer might write one of + these forms: + + (let ((total 0)) (dolist (x my-list) (incf total x)) total) + (loop for x in my-list sum x) + + While this would be mainly a stylistic choice in most Common Lisps, + in Emacs Lisp you should be aware that the iterative forms are + much faster than recursion. Also, Lisp programmers will want to + note that the current Emacs Lisp compiler does not optimize tail + recursion. + + +File: cl.info, Node: Function Index, Next: Variable Index, Prev: Porting Common Lisp, Up: Top + +Function Index +************** + +* Menu: + +* abs: Numerical Functions. +* acons: Association Lists. +* adjoin: Lists as Sets. +* assert: Assertions. +* assoc*: Association Lists. +* assoc-if: Association Lists. +* assoc-if-not: Association Lists. +* block: Blocks and Exits. +* butlast: List Functions. +* caddr: List Functions. +* callf: Modify Macros. +* callf2: Modify Macros. +* case: Conditionals. +* ceiling*: Numerical Functions. +* check-type: Assertions. +* cl-float-limits: Implementation Parameters. +* cl-prettyexpand: Efficiency Concerns. +* coerce: Type Predicates. +* compiler-macroexpand: Macros. +* concatenate: Sequence Functions. +* copy-list: List Functions. +* copy-tree: List Functions. +* count: Searching Sequences. +* count-if: Searching Sequences. +* count-if-not: Searching Sequences. +* decf: Modify Macros. +* declaim: Declarations. +* declare: Declarations. +* defalias: Function Aliases. +* define-compiler-macro: Macros. +* define-modify-macro: Customizing Setf. +* define-setf-method: Customizing Setf. +* defmacro*: Argument Lists. +* defsetf: Customizing Setf. +* defstruct: Structures. +* defsubst*: Argument Lists. +* deftype: Type Predicates. +* defun*: Argument Lists. +* delete: Sequence Functions. +* delete*: Sequence Functions. +* delete-duplicates: Sequence Functions. +* delete-if: Sequence Functions. +* delete-if-not: Sequence Functions. +* destructuring-bind: Macros. +* do: Iteration. +* do*: Iteration. +* do-all-symbols: Iteration. +* do-symbols: Iteration. +* dolist: Iteration. +* dotimes: Iteration. +* ecase: Conditionals. +* endp: List Functions. +* eql: Equality Predicates. +* equalp: Equality Predicates. +* etypecase: Conditionals. +* eval-when: Time of Evaluation. +* eval-when-compile: Time of Evaluation. +* evenp: Predicates on Numbers. +* every: Mapping over Sequences. +* expt: Numerical Functions. +* fill: Sequence Functions. +* find: Searching Sequences. +* find-if: Searching Sequences. +* find-if-not: Searching Sequences. +* first: List Functions. +* flet: Function Bindings. +* floatp-safe: Predicates on Numbers. +* floor*: Numerical Functions. +* function*: Argument Lists. +* gcd: Numerical Functions. +* gensym: Creating Symbols. +* gentemp: Creating Symbols. +* get-setf-method: Customizing Setf. +* getf: Property Lists. +* ignore-errors: Assertions. +* incf: Modify Macros. +* intersection: Lists as Sets. +* isqrt: Numerical Functions. +* labels: Function Bindings. +* last: List Functions. +* lcm: Numerical Functions. +* ldiff: List Functions. +* letf: Modify Macros. +* letf*: Modify Macros. +* lexical-let: Lexical Bindings. +* lexical-let*: Lexical Bindings. +* list*: List Functions. +* list-length: List Functions. +* load-time-value: Time of Evaluation. +* locally: Declarations. +* loop <1>: Loop Basics. +* loop: Iteration. +* macrolet: Macro Bindings. +* make-random-state: Random Numbers. +* map: Mapping over Sequences. +* mapc: Mapping over Sequences. +* mapcan: Mapping over Sequences. +* mapcar*: Mapping over Sequences. +* mapcon: Mapping over Sequences. +* mapl: Mapping over Sequences. +* maplist: Mapping over Sequences. +* member: Lists as Sets. +* member*: Lists as Sets. +* member-if: Lists as Sets. +* member-if-not: Lists as Sets. +* merge: Sorting Sequences. +* minusp: Predicates on Numbers. +* mismatch: Searching Sequences. +* mod*: Numerical Functions. +* multiple-value-bind: Multiple Values. +* multiple-value-setq: Multiple Values. +* nbutlast: List Functions. +* nintersection: Lists as Sets. +* notany: Mapping over Sequences. +* notevery: Mapping over Sequences. +* nset-difference: Lists as Sets. +* nset-exclusive-or: Lists as Sets. +* nsublis: Substitution of Expressions. +* nsubst: Substitution of Expressions. +* nsubst-if: Substitution of Expressions. +* nsubst-if-not: Substitution of Expressions. +* nsubstitute: Sequence Functions. +* nsubstitute-if: Sequence Functions. +* nsubstitute-if-not: Sequence Functions. +* nunion: Lists as Sets. +* oddp: Predicates on Numbers. +* pairlis: Association Lists. +* plusp: Predicates on Numbers. +* pop: Modify Macros. +* position: Searching Sequences. +* position-if: Searching Sequences. +* position-if-not: Searching Sequences. +* proclaim: Declarations. +* progv: Dynamic Bindings. +* psetf: Modify Macros. +* psetq: Assignment. +* push: Modify Macros. +* pushnew: Modify Macros. +* random*: Random Numbers. +* random-state-p: Random Numbers. +* rassoc: Association Lists. +* rassoc*: Association Lists. +* rassoc-if: Association Lists. +* rassoc-if-not: Association Lists. +* reduce: Mapping over Sequences. +* rem*: Numerical Functions. +* remf: Property Lists. +* remove: Sequence Functions. +* remove*: Sequence Functions. +* remove-duplicates: Sequence Functions. +* remove-if: Sequence Functions. +* remove-if-not: Sequence Functions. +* remq: Sequence Functions. +* replace: Sequence Functions. +* rest: List Functions. +* return: Blocks and Exits. +* return-from: Blocks and Exits. +* rotatef: Modify Macros. +* round*: Numerical Functions. +* search: Searching Sequences. +* set-difference: Lists as Sets. +* set-exclusive-or: Lists as Sets. +* setf: Basic Setf. +* shiftf: Modify Macros. +* some: Mapping over Sequences. +* sort*: Sorting Sequences. +* stable-sort: Sorting Sequences. +* sublis: Substitution of Expressions. +* subseq: Sequence Functions. +* subsetp: Lists as Sets. +* subst: Substitution of Expressions. +* subst-if: Substitution of Expressions. +* subst-if-not: Substitution of Expressions. +* substitute: Sequence Functions. +* substitute-if: Sequence Functions. +* substitute-if-not: Sequence Functions. +* symbol-macrolet: Macro Bindings. +* tailp: Lists as Sets. +* the: Declarations. +* tree-equal: List Functions. +* truncate*: Numerical Functions. +* typecase: Conditionals. +* typep: Type Predicates. +* union: Lists as Sets. +* unless: Conditionals. +* when: Conditionals. + + +File: cl.info, Node: Variable Index, Prev: Function Index, Up: Top + +Variable Index +************** + +* Menu: + +* *gensym-counter*: Creating Symbols. +* *random-state*: Random Numbers. +* float-epsilon: Implementation Parameters. +* float-negative-epsilon: Implementation Parameters. +* least-negative-float: Implementation Parameters. +* least-negative-normalized-float: Implementation Parameters. +* least-positive-float: Implementation Parameters. +* least-positive-normalized-float: Implementation Parameters. +* most-negative-fixnum: Implementation Parameters. +* most-negative-float: Implementation Parameters. +* most-positive-fixnum: Implementation Parameters. +* most-positive-float: Implementation Parameters. + +  Tag Table: -(Indirect) Node: Top1164 Node: Overview2716 Node: Usage4995 diff -u -r -N xemacs-21.4.14/info/cl.info-1 xemacs-21.4.15/info/cl.info-1 --- xemacs-21.4.14/info/cl.info-1 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-1 1969-12-31 19:00:00.000000000 -0500 @@ -1,1038 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: Top, Next: Overview, Up: (dir) - -Common Lisp Extensions -********************** - -This document describes a set of Emacs Lisp facilities borrowed from -Common Lisp. All the facilities are described here in detail; for more -discussion and examples, Guy L. Steele's `Common Lisp, the Language', -second edition, is the definitive book on Common Lisp. While this -document does not assume any prior knowledge of Common Lisp, it does -assume a basic familiarity with Emacs Lisp. - -* Menu: - -* Overview:: Installation, usage, etc. -* Program Structure:: Arglists, `eval-when', `defalias' -* Predicates:: `typep', `eql', and `equalp' -* Control Structure:: `setf', `when', `do', `loop', etc. -* Macros:: Destructuring, `define-compiler-macro' -* Declarations:: `proclaim', `declare', etc. -* Symbols:: Property lists, `gensym' -* Numbers:: Predicates, functions, random numbers -* Sequences:: Mapping, functions, searching, sorting -* Lists:: `cadr', `sublis', `member*', `assoc*', etc. -* Hash Tables:: `make-hash-table', `gethash', etc. -* Structures:: `defstruct' -* Assertions:: `check-type', `assert', `ignore-errors'. - -* Efficiency Concerns:: Hints and techniques -* Common Lisp Compatibility:: All known differences with Steele -* Old CL Compatibility:: All known differences with old cl.el -* Porting Common Lisp:: Hints for porting Common Lisp code - -* Function Index:: -* Variable Index:: - - -File: cl.info, Node: Overview, Next: Program Structure, Prev: Top, Up: Top - -Overview -******** - -Common Lisp is a huge language, and Common Lisp systems tend to be -massive and extremely complex. Emacs Lisp, by contrast, is rather -minimalist in the choice of Lisp features it offers the programmer. As -Emacs Lisp programmers have grown in number, and the applications they -write have grown more ambitious, it has become clear that Emacs Lisp -could benefit from many of the conveniences of Common Lisp. - - The "CL" package adds a number of Common Lisp functions and control -structures to Emacs Lisp. While not a 100% complete implementation of -Common Lisp, "CL" adds enough functionality to make Emacs Lisp -programming significantly more convenient. - - Some Common Lisp features have been omitted from this package for -various reasons: - - * Some features are too complex or bulky relative to their benefit - to Emacs Lisp programmers. CLOS and Common Lisp streams are fine - examples of this group. - - * Other features cannot be implemented without modification to the - Emacs Lisp interpreter itself, such as multiple return values, - lexical scoping, case-insensitive symbols, and complex numbers. - The "CL" package generally makes no attempt to emulate these - features. - - * Some features conflict with existing things in Emacs Lisp. For - example, Emacs' `assoc' function is incompatible with the Common - Lisp `assoc'. In such cases, this package usually adds the suffix - `*' to the function name of the Common Lisp version of the - function (e.g., `assoc*'). - - The package described here was written by Dave Gillespie, -`daveg@synaptics.com'. It is a total rewrite of the original 1986 -`cl.el' package by Cesar Quiroz. Most features of the Quiroz package -have been retained; any incompatibilities are noted in the descriptions -below. Care has been taken in this version to ensure that each -function is defined efficiently, concisely, and with minimal impact on -the rest of the Emacs environment. - -* Menu: - -* Usage:: How to use the CL package -* Organization:: The package's five component files -* Installation:: Compiling and installing CL -* Naming Conventions:: Notes on CL function names - - -File: cl.info, Node: Usage, Next: Organization, Prev: Overview, Up: Overview - -Usage -===== - -Lisp code that uses features from the "CL" package should include at -the beginning: - - (require 'cl) - -If you want to ensure that the new (Gillespie) version of "CL" is the -one that is present, add an additional `(require 'cl-19)' call: - - (require 'cl) - (require 'cl-19) - -The second call will fail (with "`cl-19.el' not found") if the old -`cl.el' package was in use. - - It is safe to arrange to load "CL" at all times, e.g., in your -`.emacs' file. But it's a good idea, for portability, to `(require -'cl)' in your code even if you do this. - - -File: cl.info, Node: Organization, Next: Installation, Prev: Usage, Up: Overview - -Organization -============ - -The Common Lisp package is organized into four files: - -`cl.el' - This is the "main" file, which contains basic functions and - information about the package. This file is relatively - compact--about 700 lines. - -`cl-extra.el' - This file contains the larger, more complex or unusual functions. - It is kept separate so that packages which only want to use Common - Lisp fundamentals like the `cadr' function won't need to pay the - overhead of loading the more advanced functions. - -`cl-seq.el' - This file contains most of the advanced functions for operating on - sequences or lists, such as `delete-if' and `assoc*'. - -`cl-macs.el' - This file contains the features of the packages which are macros - instead of functions. Macros expand when the caller is compiled, - not when it is run, so the macros generally only need to be - present when the byte-compiler is running (or when the macros are - used in uncompiled code such as a `.emacs' file). Most of the - macros of this package are isolated in `cl-macs.el' so that they - won't take up memory unless you are compiling. - - The file `cl.el' includes all necessary `autoload' commands for the -functions and macros in the other three files. All you have to do is -`(require 'cl)', and `cl.el' will take care of pulling in the other -files when they are needed. - - There is another file, `cl-compat.el', which defines some routines -from the older `cl.el' package that are no longer present in the new -package. This includes internal routines like `setelt' and -`zip-lists', deprecated features like `defkeyword', and an emulation of -the old-style multiple-values feature. *Note Old CL Compatibility::. - - -File: cl.info, Node: Installation, Next: Naming Conventions, Prev: Organization, Up: Overview - -Installation -============ - -Installation of the "CL" package is simple: Just put the byte-compiled -files `cl.elc', `cl-extra.elc', `cl-seq.elc', `cl-macs.elc', and -`cl-compat.elc' into a directory on your `load-path'. - - There are no special requirements to compile this package: The files -do not have to be loaded before they are compiled, nor do they need to -be compiled in any particular order. - - You may choose to put the files into your main `lisp/' directory, -replacing the original `cl.el' file there. Or, you could put them into -a directory that comes before `lisp/' on your `load-path' so that the -old `cl.el' is effectively hidden. - - Also, format the `cl.texinfo' file and put the resulting Info files -in the `info/' directory or another suitable place. - - You may instead wish to leave this package's components all in their -own directory, and then add this directory to your `load-path' and -(Emacs 19 only) `Info-directory-list'. Add the directory to the front -of the list so the old "CL" package and its documentation are hidden. - - -File: cl.info, Node: Naming Conventions, Prev: Installation, Up: Overview - -Naming Conventions -================== - -Except where noted, all functions defined by this package have the same -names and calling conventions as their Common Lisp counterparts. - - Following is a complete list of functions whose names were changed -from Common Lisp, usually to avoid conflicts with Emacs. In each case, -a `*' has been appended to the Common Lisp name to obtain the Emacs -name: - - defun* defsubst* defmacro* function* - member* assoc* rassoc* remove* - delete* mapcar* sort* floor* - ceiling* truncate* round* mod* - rem* random* - - Internal function and variable names in the package are prefixed by -`cl-'. Here is a complete list of functions _not_ prefixed by `cl-' -which were not taken from Common Lisp: - - member delete remove remq - rassoc floatp-safe lexical-let lexical-let* - callf callf2 letf letf* - defsubst* defalias add-hook eval-when-compile - -(Most of these are Emacs 19 features provided to Emacs 18 users, or -introduced, like `remq', for reasons of symmetry with similar features.) - - The following simple functions and macros are defined in `cl.el'; -they do not cause other components like `cl-extra' to be loaded. - - eql floatp-safe abs endp - evenp oddp plusp minusp - last butlast nbutlast caar .. cddddr - list* ldiff rest first .. tenth - member [1] copy-list subst mapcar* [2] - adjoin [3] acons pairlis when - unless pop [4] push [4] pushnew [3,4] - incf [4] decf [4] proclaim declaim - add-hook - -[1] This is the Emacs 19-compatible function, not `member*'. - -[2] Only for one sequence argument or two list arguments. - -[3] Only if `:test' is `eq', `equal', or unspecified, and `:key' is not -used. - -[4] Only when PLACE is a plain variable name. - - -File: cl.info, Node: Program Structure, Next: Predicates, Prev: Overview, Up: Top - -Program Structure -***************** - -This section describes features of the "CL" package which have to do -with programs as a whole: advanced argument lists for functions, and -the `eval-when' construct. - -* Menu: - -* Argument Lists:: `&key', `&aux', `defun*', `defmacro*'. -* Time of Evaluation:: The `eval-when' construct. -* Function Aliases:: The `defalias' function. - - -File: cl.info, Node: Argument Lists, Next: Time of Evaluation, Prev: Program Structure, Up: Program Structure - -Argument Lists -============== - -Emacs Lisp's notation for argument lists of functions is a subset of -the Common Lisp notation. As well as the familiar `&optional' and -`&rest' markers, Common Lisp allows you to specify default values for -optional arguments, and it provides the additional markers `&key' and -`&aux'. - - Since argument parsing is built-in to Emacs, there is no way for -this package to implement Common Lisp argument lists seamlessly. -Instead, this package defines alternates for several Lisp forms which -you must use if you need Common Lisp argument lists. - - - Special Form: defun* name arglist body... - This form is identical to the regular `defun' form, except that - ARGLIST is allowed to be a full Common Lisp argument list. Also, - the function body is enclosed in an implicit block called NAME; - *note Blocks and Exits::. - - - Special Form: defsubst* name arglist body... - This is just like `defun*', except that the function that is - defined is automatically proclaimed `inline', i.e., calls to it - may be expanded into in-line code by the byte compiler. This is - analogous to the `defsubst' form in Emacs 19; `defsubst*' uses a - different method (compiler macros) which works in all version of - Emacs, and also generates somewhat more efficient inline - expansions. In particular, `defsubst*' arranges for the - processing of keyword arguments, default values, etc., to be done - at compile-time whenever possible. - - - Special Form: defmacro* name arglist body... - This is identical to the regular `defmacro' form, except that - ARGLIST is allowed to be a full Common Lisp argument list. The - `&environment' keyword is supported as described in Steele. The - `&whole' keyword is supported only within destructured lists (see - below); top-level `&whole' cannot be implemented with the current - Emacs Lisp interpreter. The macro expander body is enclosed in an - implicit block called NAME. - - - Special Form: function* symbol-or-lambda - This is identical to the regular `function' form, except that if - the argument is a `lambda' form then that form may use a full - Common Lisp argument list. - - Also, all forms (such as `defsetf' and `flet') defined in this -package that include ARGLISTs in their syntax allow full Common Lisp -argument lists. - - Note that it is _not_ necessary to use `defun*' in order to have -access to most "CL" features in your function. These features are -always present; `defun*''s only difference from `defun' is its more -flexible argument lists and its implicit block. - - The full form of a Common Lisp argument list is - - (VAR... - &optional (VAR INITFORM SVAR)... - &rest VAR - &key ((KEYWORD VAR) INITFORM SVAR)... - &aux (VAR INITFORM)...) - - Each of the five argument list sections is optional. The SVAR, -INITFORM, and KEYWORD parts are optional; if they are omitted, then -`(VAR)' may be written simply `VAR'. - - The first section consists of zero or more "required" arguments. -These arguments must always be specified in a call to the function; -there is no difference between Emacs Lisp and Common Lisp as far as -required arguments are concerned. - - The second section consists of "optional" arguments. These -arguments may be specified in the function call; if they are not, -INITFORM specifies the default value used for the argument. (No -INITFORM means to use `nil' as the default.) The INITFORM is evaluated -with the bindings for the preceding arguments already established; `(a -&optional (b (1+ a)))' matches one or two arguments, with the second -argument defaulting to one plus the first argument. If the SVAR is -specified, it is an auxiliary variable which is bound to `t' if the -optional argument was specified, or to `nil' if the argument was -omitted. If you don't use an SVAR, then there will be no way for your -function to tell whether it was called with no argument, or with the -default value passed explicitly as an argument. - - The third section consists of a single "rest" argument. If more -arguments were passed to the function than are accounted for by the -required and optional arguments, those extra arguments are collected -into a list and bound to the "rest" argument variable. Common Lisp's -`&rest' is equivalent to that of Emacs Lisp. Common Lisp accepts -`&body' as a synonym for `&rest' in macro contexts; this package -accepts it all the time. - - The fourth section consists of "keyword" arguments. These are -optional arguments which are specified by name rather than positionally -in the argument list. For example, - - (defun* foo (a &optional b &key c d (e 17))) - -defines a function which may be called with one, two, or more -arguments. The first two arguments are bound to `a' and `b' in the -usual way. The remaining arguments must be pairs of the form `:c', -`:d', or `:e' followed by the value to be bound to the corresponding -argument variable. (Symbols whose names begin with a colon are called -"keywords", and they are self-quoting in the same way as `nil' and `t'.) - - For example, the call `(foo 1 2 :d 3 :c 4)' sets the five arguments -to 1, 2, 4, 3, and 17, respectively. If the same keyword appears more -than once in the function call, the first occurrence takes precedence -over the later ones. Note that it is not possible to specify keyword -arguments without specifying the optional argument `b' as well, since -`(foo 1 :c 2)' would bind `b' to the keyword `:c', then signal an error -because `2' is not a valid keyword. - - If a KEYWORD symbol is explicitly specified in the argument list as -shown in the above diagram, then that keyword will be used instead of -just the variable name prefixed with a colon. You can specify a -KEYWORD symbol which does not begin with a colon at all, but such -symbols will not be self-quoting; you will have to quote them -explicitly with an apostrophe in the function call. - - Ordinarily it is an error to pass an unrecognized keyword to a -function, e.g., `(foo 1 2 :c 3 :goober 4)'. You can ask Lisp to ignore -unrecognized keywords, either by adding the marker `&allow-other-keys' -after the keyword section of the argument list, or by specifying an -`:allow-other-keys' argument in the call whose value is non-`nil'. If -the function uses both `&rest' and `&key' at the same time, the "rest" -argument is bound to the keyword list as it appears in the call. For -example: - - (defun* find-thing (thing &rest rest &key need &allow-other-keys) - (or (apply 'member* thing thing-list :allow-other-keys t rest) - (if need (error "Thing not found")))) - -This function takes a `:need' keyword argument, but also accepts other -keyword arguments which are passed on to the `member*' function. -`allow-other-keys' is used to keep both `find-thing' and `member*' from -complaining about each others' keywords in the arguments. - - As a (significant) performance optimization, this package implements -the scan for keyword arguments by calling `memq' to search for keywords -in a "rest" argument. Technically speaking, this is incorrect, since -`memq' looks at the odd-numbered values as well as the even-numbered -keywords. The net effect is that if you happen to pass a keyword symbol -as the _value_ of another keyword argument, where that keyword symbol -happens to equal the name of a valid keyword argument of the same -function, then the keyword parser will become confused. This minor bug -can only affect you if you use keyword symbols as general-purpose data -in your program; this practice is strongly discouraged in Emacs Lisp. - - The fifth section of the argument list consists of "auxiliary -variables". These are not really arguments at all, but simply -variables which are bound to `nil' or to the specified INITFORMS during -execution of the function. There is no difference between the -following two functions, except for a matter of stylistic taste: - - (defun* foo (a b &aux (c (+ a b)) d) - BODY) - - (defun* foo (a b) - (let ((c (+ a b)) d) - BODY)) - - Argument lists support "destructuring". In Common Lisp, -destructuring is only allowed with `defmacro'; this package allows it -with `defun*' and other argument lists as well. In destructuring, any -argument variable (VAR in the above diagram) can be replaced by a list -of variables, or more generally, a recursive argument list. The -corresponding argument value must be a list whose elements match this -recursive argument list. For example: - - (defmacro* dolist ((var listform &optional resultform) - &rest body) - ...) - - This says that the first argument of `dolist' must be a list of two -or three items; if there are other arguments as well as this list, they -are stored in `body'. All features allowed in regular argument lists -are allowed in these recursive argument lists. In addition, the clause -`&whole VAR' is allowed at the front of a recursive argument list. It -binds VAR to the whole list being matched; thus `(&whole all a b)' -matches a list of two things, with `a' bound to the first thing, `b' -bound to the second thing, and `all' bound to the list itself. (Common -Lisp allows `&whole' in top-level `defmacro' argument lists as well, -but Emacs Lisp does not support this usage.) - - One last feature of destructuring is that the argument list may be -dotted, so that the argument list `(a b . c)' is functionally -equivalent to `(a b &rest c)'. - - If the optimization quality `safety' is set to 0 (*note -Declarations::), error checking for wrong number of arguments and -invalid keyword arguments is disabled. By default, argument lists are -rigorously checked. - - -File: cl.info, Node: Time of Evaluation, Next: Function Aliases, Prev: Argument Lists, Up: Program Structure - -Time of Evaluation -================== - -Normally, the byte-compiler does not actually execute the forms in a -file it compiles. For example, if a file contains `(setq foo t)', the -act of compiling it will not actually set `foo' to `t'. This is true -even if the `setq' was a top-level form (i.e., not enclosed in a -`defun' or other form). Sometimes, though, you would like to have -certain top-level forms evaluated at compile-time. For example, the -compiler effectively evaluates `defmacro' forms at compile-time so that -later parts of the file can refer to the macros that are defined. - - - Special Form: eval-when (situations...) forms... - This form controls when the body FORMS are evaluated. The - SITUATIONS list may contain any set of the symbols `compile', - `load', and `eval' (or their long-winded ANSI equivalents, - `:compile-toplevel', `:load-toplevel', and `:execute'). - - The `eval-when' form is handled differently depending on whether - or not it is being compiled as a top-level form. Specifically, it - gets special treatment if it is being compiled by a command such - as `byte-compile-file' which compiles files or buffers of code, - and it appears either literally at the top level of the file or - inside a top-level `progn'. - - For compiled top-level `eval-when's, the body FORMS are executed - at compile-time if `compile' is in the SITUATIONS list, and the - FORMS are written out to the file (to be executed at load-time) if - `load' is in the SITUATIONS list. - - For non-compiled-top-level forms, only the `eval' situation is - relevant. (This includes forms executed by the interpreter, forms - compiled with `byte-compile' rather than `byte-compile-file', and - non-top-level forms.) The `eval-when' acts like a `progn' if - `eval' is specified, and like `nil' (ignoring the body FORMS) if - not. - - The rules become more subtle when `eval-when's are nested; consult - Steele (second edition) for the gruesome details (and some - gruesome examples). - - Some simple examples: - - ;; Top-level forms in foo.el: - (eval-when (compile) (setq foo1 'bar)) - (eval-when (load) (setq foo2 'bar)) - (eval-when (compile load) (setq foo3 'bar)) - (eval-when (eval) (setq foo4 'bar)) - (eval-when (eval compile) (setq foo5 'bar)) - (eval-when (eval load) (setq foo6 'bar)) - (eval-when (eval compile load) (setq foo7 'bar)) - - When `foo.el' is compiled, these variables will be set during the - compilation itself: - - foo1 foo3 foo5 foo7 ; `compile' - - When `foo.elc' is loaded, these variables will be set: - - foo2 foo3 foo6 foo7 ; `load' - - And if `foo.el' is loaded uncompiled, these variables will be set: - - foo4 foo5 foo6 foo7 ; `eval' - - If these seven `eval-when's had been, say, inside a `defun', then - the first three would have been equivalent to `nil' and the last - four would have been equivalent to the corresponding `setq's. - - Note that `(eval-when (load eval) ...)' is equivalent to `(progn - ...)' in all contexts. The compiler treats certain top-level - forms, like `defmacro' (sort-of) and `require', as if they were - wrapped in `(eval-when (compile load eval) ...)'. - - Emacs 19 includes two special forms related to `eval-when'. One of -these, `eval-when-compile', is not quite equivalent to any `eval-when' -construct and is described below. This package defines a version of -`eval-when-compile' for the benefit of Emacs 18 users. - - The other form, `(eval-and-compile ...)', is exactly equivalent to -`(eval-when (compile load eval) ...)' and so is not itself defined by -this package. - - - Special Form: eval-when-compile forms... - The FORMS are evaluated at compile-time; at execution time, this - form acts like a quoted constant of the resulting value. Used at - top-level, `eval-when-compile' is just like `eval-when (compile - eval)'. In other contexts, `eval-when-compile' allows code to be - evaluated once at compile-time for efficiency or other reasons. - - This form is similar to the `#.' syntax of true Common Lisp. - - - Special Form: load-time-value form - The FORM is evaluated at load-time; at execution time, this form - acts like a quoted constant of the resulting value. - - Early Common Lisp had a `#,' syntax that was similar to this, but - ANSI Common Lisp replaced it with `load-time-value' and gave it - more well-defined semantics. - - In a compiled file, `load-time-value' arranges for FORM to be - evaluated when the `.elc' file is loaded and then used as if it - were a quoted constant. In code compiled by `byte-compile' rather - than `byte-compile-file', the effect is identical to - `eval-when-compile'. In uncompiled code, both `eval-when-compile' - and `load-time-value' act exactly like `progn'. - - (defun report () - (insert "This function was executed on: " - (current-time-string) - ", compiled on: " - (eval-when-compile (current-time-string)) - ;; or '#.(current-time-string) in real Common Lisp - ", and loaded on: " - (load-time-value (current-time-string)))) - - Byte-compiled, the above defun will result in the following code - (or its compiled equivalent, of course) in the `.elc' file: - - (setq --temp-- (current-time-string)) - (defun report () - (insert "This function was executed on: " - (current-time-string) - ", compiled on: " - '"Wed Jun 23 18:33:43 1993" - ", and loaded on: " - --temp--)) - - -File: cl.info, Node: Function Aliases, Prev: Time of Evaluation, Up: Program Structure - -Function Aliases -================ - -This section describes a feature from GNU Emacs 19 which this package -makes available in other versions of Emacs. - - - Function: defalias symbol function - This function sets SYMBOL's function cell to FUNCTION. It is - equivalent to `fset', except that in GNU Emacs 19 it also records - the setting in `load-history' so that it can be undone by a later - `unload-feature'. - - In other versions of Emacs, `defalias' is a synonym for `fset'. - - -File: cl.info, Node: Predicates, Next: Control Structure, Prev: Program Structure, Up: Top - -Predicates -********** - -This section describes functions for testing whether various facts are -true or false. - -* Menu: - -* Type Predicates:: `typep', `deftype', and `coerce' -* Equality Predicates:: `eql' and `equalp' - - -File: cl.info, Node: Type Predicates, Next: Equality Predicates, Prev: Predicates, Up: Predicates - -Type Predicates -=============== - -The "CL" package defines a version of the Common Lisp `typep' predicate. - - - Function: typep object type - Check if OBJECT is of type TYPE, where TYPE is a (quoted) type - name of the sort used by Common Lisp. For example, `(typep foo - 'integer)' is equivalent to `(integerp foo)'. - - The TYPE argument to the above function is either a symbol or a list -beginning with a symbol. - - * If the type name is a symbol, Emacs appends `-p' to the symbol - name to form the name of a predicate function for testing the - type. (Built-in predicates whose names end in `p' rather than - `-p' are used when appropriate.) - - * The type symbol `t' stands for the union of all types. `(typep - OBJECT t)' is always true. Likewise, the type symbol `nil' stands - for nothing at all, and `(typep OBJECT nil)' is always false. - - * The type symbol `null' represents the symbol `nil'. Thus `(typep - OBJECT 'null)' is equivalent to `(null OBJECT)'. - - * The type symbol `real' is a synonym for `number', and `fixnum' is - a synonym for `integer'. - - * The type symbols `character' and `string-char' match characters. - In Emacs-19 and XEmacs-19, characters are the same thing as - integers in the range 0-255. In XEmacs-20, where characters are a - first-class data type, this checks for actual characters, and - `(typep 8BIT-INTEGER 'character)' will return `nil'. - - * The type symbol `float' uses the `floatp-safe' predicate defined - by this package rather than `floatp', so it will work correctly - even in Emacs versions without floating-point support. - - * The type list `(integer LOW HIGH)' represents all integers between - LOW and HIGH, inclusive. Either bound may be a list of a single - integer to specify an exclusive limit, or a `*' to specify no - limit. The type `(integer * *)' is thus equivalent to `integer'. - - * Likewise, lists beginning with `float', `real', or `number' - represent numbers of that type falling in a particular range. - - * Lists beginning with `and', `or', and `not' form combinations of - types. For example, `(or integer (float 0 *))' represents all - objects that are integers or non-negative floats. - - * Lists beginning with `member' or `member*' represent objects `eql' - to any of the following values. For example, `(member 1 2 3 4)' - is equivalent to `(integer 1 4)', and `(member nil)' is equivalent - to `null'. - - * Lists of the form `(satisfies PREDICATE)' represent all objects - for which PREDICATE returns true when called with that object as - an argument. - - The following function and macro (not technically predicates) are -related to `typep'. - - - Function: coerce object type - This function attempts to convert OBJECT to the specified TYPE. - If OBJECT is already of that type as determined by `typep', it is - simply returned. Otherwise, certain types of conversions will be - made: If TYPE is any sequence type (`string', `list', etc.) then - OBJECT will be converted to that type if possible. If TYPE is - `character', then strings of length one and symbols with - one-character names can be coerced. If TYPE is `float', then - integers can be coerced in versions of Emacs that support floats. - In all other circumstances, `coerce' signals an error. - - - Special Form: deftype name arglist forms... - This macro defines a new type called NAME. It is similar to - `defmacro' in many ways; when NAME is encountered as a type name, - the body FORMS are evaluated and should return a type specifier - that is equivalent to the type. The ARGLIST is a Common Lisp - argument list of the sort accepted by `defmacro*'. The type - specifier `(NAME ARGS...)' is expanded by calling the expander - with those arguments; the type symbol `NAME' is expanded by - calling the expander with no arguments. The ARGLIST is processed - the same as for `defmacro*' except that optional arguments without - explicit defaults use `*' instead of `nil' as the "default" - default. Some examples: - - (deftype null () '(satisfies null)) ; predefined - (deftype list () '(or null cons)) ; predefined - (deftype unsigned-byte (&optional bits) - (list 'integer 0 (if (eq bits '*) bits (1- (lsh 1 bits))))) - (unsigned-byte 8) == (integer 0 255) - (unsigned-byte) == (integer 0 *) - unsigned-byte == (integer 0 *) - - The last example shows how the Common Lisp `unsigned-byte' type - specifier could be implemented if desired; this package does not - implement `unsigned-byte' by default. - - The `typecase' and `check-type' macros also use type names. *Note -Conditionals::. *Note Assertions::. The `map', `concatenate', and -`merge' functions take type-name arguments to specify the type of -sequence to return. *Note Sequences::. - - -File: cl.info, Node: Equality Predicates, Prev: Type Predicates, Up: Predicates - -Equality Predicates -=================== - -This package defines two Common Lisp predicates, `eql' and `equalp'. - - - Function: eql a b - This function is almost the same as `eq', except that if A and B - are numbers of the same type, it compares them for numeric - equality (as if by `equal' instead of `eq'). This makes a - difference only for versions of Emacs that are compiled with - floating-point support, such as Emacs 19. Emacs floats are - allocated objects just like cons cells, which means that `(eq 3.0 - 3.0)' will not necessarily be true--if the two `3.0's were - allocated separately, the pointers will be different even though - the numbers are the same. But `(eql 3.0 3.0)' will always be true. - - The types of the arguments must match, so `(eql 3 3.0)' is still - false. - - Note that Emacs integers are "direct" rather than allocated, which - basically means `(eq 3 3)' will always be true. Thus `eq' and - `eql' behave differently only if floating-point numbers are - involved, and are indistinguishable on Emacs versions that don't - support floats. - - There is a slight inconsistency with Common Lisp in the treatment - of positive and negative zeros. Some machines, notably those with - IEEE standard arithmetic, represent `+0' and `-0' as distinct - values. Normally this doesn't matter because the standard - specifies that `(= 0.0 -0.0)' should always be true, and this is - indeed what Emacs Lisp and Common Lisp do. But the Common Lisp - standard states that `(eql 0.0 -0.0)' and `(equal 0.0 -0.0)' should - be false on IEEE-like machines; Emacs Lisp does not do this, and in - fact the only known way to distinguish between the two zeros in - Emacs Lisp is to `format' them and check for a minus sign. - - - Function: equalp a b - This function is a more flexible version of `equal'. In - particular, it compares strings and characters case-insensitively, - and it compares numbers without regard to type (so that `(equalp 3 - 3.0)' is true). Vectors and conses are compared recursively. All - other objects are compared as if by `equal'. - - This function differs from Common Lisp `equalp' in several - respects. In keeping with the idea that strings are less - vector-like in Emacs Lisp, this package's `equalp' also will not - compare strings against vectors of integers. - - Also note that the Common Lisp functions `member' and `assoc' use -`eql' to compare elements, whereas Emacs Lisp follows the MacLisp -tradition and uses `equal' for these two functions. In Emacs, use -`member*' and `assoc*' to get functions which use `eql' for comparisons. - - -File: cl.info, Node: Control Structure, Next: Macros, Prev: Predicates, Up: Top - -Control Structure -***************** - -The features described in the following sections implement various -advanced control structures, including the powerful `setf' facility and -a number of looping and conditional constructs. - -* Menu: - -* Assignment:: The `psetq' form -* Generalized Variables:: `setf', `incf', `push', etc. -* Variable Bindings:: `progv', `lexical-let', `flet', `macrolet' -* Conditionals:: `when', `unless', `case', `typecase' -* Blocks and Exits:: `block', `return', `return-from' -* Iteration:: `do', `dotimes', `dolist', `do-symbols' -* Loop Facility:: The Common Lisp `loop' macro -* Multiple Values:: `values', `multiple-value-bind', etc. - - -File: cl.info, Node: Assignment, Next: Generalized Variables, Prev: Control Structure, Up: Control Structure - -Assignment -========== - -The `psetq' form is just like `setq', except that multiple assignments -are done in parallel rather than sequentially. - - - Special Form: psetq [symbol form]... - This special form (actually a macro) is used to assign to several - variables simultaneously. Given only one SYMBOL and FORM, it has - the same effect as `setq'. Given several SYMBOL and FORM pairs, - it evaluates all the FORMs in advance and then stores the - corresponding variables afterwards. - - (setq x 2 y 3) - (setq x (+ x y) y (* x y)) - x - => 5 - y ; `y' was computed after `x' was set. - => 15 - (setq x 2 y 3) - (psetq x (+ x y) y (* x y)) - x - => 5 - y ; `y' was computed before `x' was set. - => 6 - - The simplest use of `psetq' is `(psetq x y y x)', which exchanges - the values of two variables. (The `rotatef' form provides an even - more convenient way to swap two variables; *note Modify Macros::.) - - `psetq' always returns `nil'. - - -File: cl.info, Node: Generalized Variables, Next: Variable Bindings, Prev: Assignment, Up: Control Structure - -Generalized Variables -===================== - -A "generalized variable" or "place form" is one of the many places in -Lisp memory where values can be stored. The simplest place form is a -regular Lisp variable. But the cars and cdrs of lists, elements of -arrays, properties of symbols, and many other locations are also places -where Lisp values are stored. - - The `setf' form is like `setq', except that it accepts arbitrary -place forms on the left side rather than just symbols. For example, -`(setf (car a) b)' sets the car of `a' to `b', doing the same operation -as `(setcar a b)' but without having to remember two separate functions -for setting and accessing every type of place. - - Generalized variables are analogous to "lvalues" in the C language, -where `x = a[i]' gets an element from an array and `a[i] = x' stores an -element using the same notation. Just as certain forms like `a[i]' can -be lvalues in C, there is a set of forms that can be generalized -variables in Lisp. - -* Menu: - -* Basic Setf:: `setf' and place forms -* Modify Macros:: `incf', `push', `rotatef', `letf', `callf', etc. -* Customizing Setf:: `define-modify-macro', `defsetf', `define-setf-method' - - -File: cl.info, Node: Basic Setf, Next: Modify Macros, Prev: Generalized Variables, Up: Generalized Variables - -Basic Setf ----------- - -The `setf' macro is the most basic way to operate on generalized -variables. - - - Special Form: setf [place form]... - This macro evaluates FORM and stores it in PLACE, which must be a - valid generalized variable form. If there are several PLACE and - FORM pairs, the assignments are done sequentially just as with - `setq'. `setf' returns the value of the last FORM. - - The following Lisp forms will work as generalized variables, and - so may legally appear in the PLACE argument of `setf': - - * A symbol naming a variable. In other words, `(setf x y)' is - exactly equivalent to `(setq x y)', and `setq' itself is - strictly speaking redundant now that `setf' exists. Many - programmers continue to prefer `setq' for setting simple - variables, though, purely for stylistic or historical reasons. - The form `(setf x y)' actually expands to `(setq x y)', so - there is no performance penalty for using it in compiled code. - - * A call to any of the following Lisp functions: - - car cdr caar .. cddddr - nth rest first .. tenth - aref elt nthcdr - symbol-function symbol-value symbol-plist - get getf gethash - subseq - - Note that for `nthcdr' and `getf', the list argument of the - function must itself be a valid PLACE form. For example, - `(setf (nthcdr 0 foo) 7)' will set `foo' itself to 7. Note - that `push' and `pop' on an `nthcdr' place can be used to - insert or delete at any position in a list. The use of - `nthcdr' as a PLACE form is an extension to standard Common - Lisp. - - * The following Emacs-specific functions are also `setf'-able. - (Some of these are defined only in Emacs 19 or only in - XEmacs.) - - buffer-file-name marker-position - buffer-modified-p match-data - buffer-name mouse-position - buffer-string overlay-end - buffer-substring overlay-get - current-buffer overlay-start - current-case-table point - current-column point-marker - current-global-map point-max - current-input-mode point-min - current-local-map process-buffer - current-window-configuration process-filter - default-file-modes process-sentinel - default-value read-mouse-position - documentation-property screen-height - extent-data screen-menubar - extent-end-position screen-width - extent-start-position selected-window - face-background selected-screen - face-background-pixmap selected-frame - face-font standard-case-table - face-foreground syntax-table - face-underline-p window-buffer - file-modes window-dedicated-p - frame-height window-display-table - frame-parameters window-height - frame-visible-p window-hscroll - frame-width window-point - get-register window-start - getenv window-width - global-key-binding x-get-cut-buffer - keymap-parent x-get-cutbuffer - local-key-binding x-get-secondary-selection - mark x-get-selection - mark-marker - - Most of these have directly corresponding "set" functions, - like `use-local-map' for `current-local-map', or `goto-char' - for `point'. A few, like `point-min', expand to longer - sequences of code when they are `setf''d (`(narrow-to-region - x (point-max))' in this case). - - * A call of the form `(substring SUBPLACE N [M])', where - SUBPLACE is itself a legal generalized variable whose current - value is a string, and where the value stored is also a - string. The new string is spliced into the specified part of - the destination string. For example: - - (setq a (list "hello" "world")) - => ("hello" "world") - (cadr a) - => "world" - (substring (cadr a) 2 4) - => "rl" - (setf (substring (cadr a) 2 4) "o") - => "o" - (cadr a) - => "wood" - a - => ("hello" "wood") - - The generalized variable `buffer-substring', listed above, - also works in this way by replacing a portion of the current - buffer. - - * A call of the form `(apply 'FUNC ...)' or `(apply (function - FUNC) ...)', where FUNC is a `setf'-able function whose store - function is "suitable" in the sense described in Steele's - book; since none of the standard Emacs place functions are - suitable in this sense, this feature is only interesting when - used with places you define yourself with - `define-setf-method' or the long form of `defsetf'. - - * A macro call, in which case the macro is expanded and `setf' - is applied to the resulting form. - - * Any form for which a `defsetf' or `define-setf-method' has - been made. - - Using any forms other than these in the PLACE argument to `setf' - will signal an error. - - The `setf' macro takes care to evaluate all subforms in the proper - left-to-right order; for example, - - (setf (aref vec (incf i)) i) - - looks like it will evaluate `(incf i)' exactly once, before the - following access to `i'; the `setf' expander will insert temporary - variables as necessary to ensure that it does in fact work this - way no matter what setf-method is defined for `aref'. (In this - case, `aset' would be used and no such steps would be necessary - since `aset' takes its arguments in a convenient order.) - - However, if the PLACE form is a macro which explicitly evaluates - its arguments in an unusual order, this unusual order will be - preserved. Adapting an example from Steele, given - - (defmacro wrong-order (x y) (list 'aref y x)) - - the form `(setf (wrong-order A B) 17)' will evaluate B first, then - A, just as in an actual call to `wrong-order'. - diff -u -r -N xemacs-21.4.14/info/cl.info-2 xemacs-21.4.15/info/cl.info-2 --- xemacs-21.4.14/info/cl.info-2 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-2 1969-12-31 19:00:00.000000000 -0500 @@ -1,1030 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: Modify Macros, Next: Customizing Setf, Prev: Basic Setf, Up: Generalized Variables - -Modify Macros -------------- - -This package defines a number of other macros besides `setf' that -operate on generalized variables. Many are interesting and useful even -when the PLACE is just a variable name. - - - Special Form: psetf [place form]... - This macro is to `setf' what `psetq' is to `setq': When several - PLACEs and FORMs are involved, the assignments take place in - parallel rather than sequentially. Specifically, all subforms are - evaluated from left to right, then all the assignments are done - (in an undefined order). - - - Special Form: incf place &optional x - This macro increments the number stored in PLACE by one, or by X - if specified. The incremented value is returned. For example, - `(incf i)' is equivalent to `(setq i (1+ i))', and `(incf (car x) - 2)' is equivalent to `(setcar x (+ (car x) 2))'. - - Once again, care is taken to preserve the "apparent" order of - evaluation. For example, - - (incf (aref vec (incf i))) - - appears to increment `i' once, then increment the element of `vec' - addressed by `i'; this is indeed exactly what it does, which means - the above form is _not_ equivalent to the "obvious" expansion, - - (setf (aref vec (incf i)) (1+ (aref vec (incf i)))) ; Wrong! - - but rather to something more like - - (let ((temp (incf i))) - (setf (aref vec temp) (1+ (aref vec temp)))) - - Again, all of this is taken care of automatically by `incf' and - the other generalized-variable macros. - - As a more Emacs-specific example of `incf', the expression `(incf - (point) N)' is essentially equivalent to `(forward-char N)'. - - - Special Form: decf place &optional x - This macro decrements the number stored in PLACE by one, or by X - if specified. - - - Special Form: pop place - This macro removes and returns the first element of the list stored - in PLACE. It is analogous to `(prog1 (car PLACE) (setf PLACE (cdr - PLACE)))', except that it takes care to evaluate all subforms only - once. - - - Special Form: push x place - This macro inserts X at the front of the list stored in PLACE. It - is analogous to `(setf PLACE (cons X PLACE))', except for - evaluation of the subforms. - - - Special Form: pushnew x place &key :test :test-not :key - This macro inserts X at the front of the list stored in PLACE, but - only if X was not `eql' to any existing element of the list. The - optional keyword arguments are interpreted in the same way as for - `adjoin'. *Note Lists as Sets::. - - - Special Form: shiftf place... newvalue - This macro shifts the PLACEs left by one, shifting in the value of - NEWVALUE (which may be any Lisp expression, not just a generalized - variable), and returning the value shifted out of the first PLACE. - Thus, `(shiftf A B C D)' is equivalent to - - (prog1 - A - (psetf A B - B C - C D)) - - except that the subforms of A, B, and C are actually evaluated - only once each and in the apparent order. - - - Special Form: rotatef place... - This macro rotates the PLACEs left by one in circular fashion. - Thus, `(rotatef A B C D)' is equivalent to - - (psetf A B - B C - C D - D A) - - except for the evaluation of subforms. `rotatef' always returns - `nil'. Note that `(rotatef A B)' conveniently exchanges A and B. - - The following macros were invented for this package; they have no -analogues in Common Lisp. - - - Special Form: letf (bindings...) forms... - This macro is analogous to `let', but for generalized variables - rather than just symbols. Each BINDING should be of the form - `(PLACE VALUE)'; the original contents of the PLACEs are saved, - the VALUEs are stored in them, and then the body FORMs are - executed. Afterwards, the PLACES are set back to their original - saved contents. This cleanup happens even if the FORMs exit - irregularly due to a `throw' or an error. - - For example, - - (letf (((point) (point-min)) - (a 17)) - ...) - - moves "point" in the current buffer to the beginning of the buffer, - and also binds `a' to 17 (as if by a normal `let', since `a' is - just a regular variable). After the body exits, `a' is set back - to its original value and point is moved back to its original - position. - - Note that `letf' on `(point)' is not quite like a - `save-excursion', as the latter effectively saves a marker which - tracks insertions and deletions in the buffer. Actually, a `letf' - of `(point-marker)' is much closer to this behavior. (`point' and - `point-marker' are equivalent as `setf' places; each will accept - either an integer or a marker as the stored value.) - - Since generalized variables look like lists, `let''s shorthand of - using `foo' for `(foo nil)' as a BINDING would be ambiguous in - `letf' and is not allowed. - - However, a BINDING specifier may be a one-element list `(PLACE)', - which is similar to `(PLACE PLACE)'. In other words, the PLACE is - not disturbed on entry to the body, and the only effect of the - `letf' is to restore the original value of PLACE afterwards. (The - redundant access-and-store suggested by the `(PLACE PLACE)' - example does not actually occur.) - - In most cases, the PLACE must have a well-defined value on entry - to the `letf' form. The only exceptions are plain variables and - calls to `symbol-value' and `symbol-function'. If the symbol is - not bound on entry, it is simply made unbound by `makunbound' or - `fmakunbound' on exit. - - - Special Form: letf* (bindings...) forms... - This macro is to `letf' what `let*' is to `let': It does the - bindings in sequential rather than parallel order. - - - Special Form: callf FUNCTION PLACE ARGS... - This is the "generic" modify macro. It calls FUNCTION, which - should be an unquoted function name, macro name, or lambda. It - passes PLACE and ARGS as arguments, and assigns the result back to - PLACE. For example, `(incf PLACE N)' is the same as `(callf + - PLACE N)'. Some more examples: - - (callf abs my-number) - (callf concat (buffer-name) "<" (int-to-string n) ">") - (callf union happy-people (list joe bob) :test 'same-person) - - *Note Customizing Setf::, for `define-modify-macro', a way to - create even more concise notations for modify macros. Note again - that `callf' is an extension to standard Common Lisp. - - - Special Form: callf2 FUNCTION ARG1 PLACE ARGS... - This macro is like `callf', except that PLACE is the _second_ - argument of FUNCTION rather than the first. For example, `(push X - PLACE)' is equivalent to `(callf2 cons X PLACE)'. - - The `callf' and `callf2' macros serve as building blocks for other -macros like `incf', `pushnew', and `define-modify-macro'. The `letf' -and `letf*' macros are used in the processing of symbol macros; *note -Macro Bindings::. - - -File: cl.info, Node: Customizing Setf, Prev: Modify Macros, Up: Generalized Variables - -Customizing Setf ----------------- - -Common Lisp defines three macros, `define-modify-macro', `defsetf', and -`define-setf-method', that allow the user to extend generalized -variables in various ways. - - - Special Form: define-modify-macro name arglist function [doc-string] - This macro defines a "read-modify-write" macro similar to `incf' - and `decf'. The macro NAME is defined to take a PLACE argument - followed by additional arguments described by ARGLIST. The call - - (NAME PLACE ARGS...) - - will be expanded to - - (callf FUNC PLACE ARGS...) - - which in turn is roughly equivalent to - - (setf PLACE (FUNC PLACE ARGS...)) - - For example: - - (define-modify-macro incf (&optional (n 1)) +) - (define-modify-macro concatf (&rest args) concat) - - Note that `&key' is not allowed in ARGLIST, but `&rest' is - sufficient to pass keywords on to the function. - - Most of the modify macros defined by Common Lisp do not exactly - follow the pattern of `define-modify-macro'. For example, `push' - takes its arguments in the wrong order, and `pop' is completely - irregular. You can define these macros "by hand" using - `get-setf-method', or consult the source file `cl-macs.el' to see - how to use the internal `setf' building blocks. - - - Special Form: defsetf access-fn update-fn - This is the simpler of two `defsetf' forms. Where ACCESS-FN is - the name of a function which accesses a place, this declares - UPDATE-FN to be the corresponding store function. From now on, - - (setf (ACCESS-FN ARG1 ARG2 ARG3) VALUE) - - will be expanded to - - (UPDATE-FN ARG1 ARG2 ARG3 VALUE) - - The UPDATE-FN is required to be either a true function, or a macro - which evaluates its arguments in a function-like way. Also, the - UPDATE-FN is expected to return VALUE as its result. Otherwise, - the above expansion would not obey the rules for the way `setf' is - supposed to behave. - - As a special (non-Common-Lisp) extension, a third argument of `t' - to `defsetf' says that the `update-fn''s return value is not - suitable, so that the above `setf' should be expanded to something - more like - - (let ((temp VALUE)) - (UPDATE-FN ARG1 ARG2 ARG3 temp) - temp) - - Some examples of the use of `defsetf', drawn from the standard - suite of setf methods, are: - - (defsetf car setcar) - (defsetf symbol-value set) - (defsetf buffer-name rename-buffer t) - - - Special Form: defsetf access-fn arglist (store-var) forms... - This is the second, more complex, form of `defsetf'. It is rather - like `defmacro' except for the additional STORE-VAR argument. The - FORMS should return a Lisp form which stores the value of - STORE-VAR into the generalized variable formed by a call to - ACCESS-FN with arguments described by ARGLIST. The FORMS may - begin with a string which documents the `setf' method (analogous - to the doc string that appears at the front of a function). - - For example, the simple form of `defsetf' is shorthand for - - (defsetf ACCESS-FN (&rest args) (store) - (append '(UPDATE-FN) args (list store))) - - The Lisp form that is returned can access the arguments from - ARGLIST and STORE-VAR in an unrestricted fashion; macros like - `setf' and `incf' which invoke this setf-method will insert - temporary variables as needed to make sure the apparent order of - evaluation is preserved. - - Another example drawn from the standard package: - - (defsetf nth (n x) (store) - (list 'setcar (list 'nthcdr n x) store)) - - - Special Form: define-setf-method access-fn arglist forms... - This is the most general way to create new place forms. When a - `setf' to ACCESS-FN with arguments described by ARGLIST is - expanded, the FORMS are evaluated and must return a list of five - items: - - 1. A list of "temporary variables". - - 2. A list of "value forms" corresponding to the temporary - variables above. The temporary variables will be bound to - these value forms as the first step of any operation on the - generalized variable. - - 3. A list of exactly one "store variable" (generally obtained - from a call to `gensym'). - - 4. A Lisp form which stores the contents of the store variable - into the generalized variable, assuming the temporaries have - been bound as described above. - - 5. A Lisp form which accesses the contents of the generalized - variable, assuming the temporaries have been bound. - - This is exactly like the Common Lisp macro of the same name, - except that the method returns a list of five values rather than - the five values themselves, since Emacs Lisp does not support - Common Lisp's notion of multiple return values. - - Once again, the FORMS may begin with a documentation string. - - A setf-method should be maximally conservative with regard to - temporary variables. In the setf-methods generated by `defsetf', - the second return value is simply the list of arguments in the - place form, and the first return value is a list of a - corresponding number of temporary variables generated by `gensym'. - Macros like `setf' and `incf' which use this setf-method will - optimize away most temporaries that turn out to be unnecessary, so - there is little reason for the setf-method itself to optimize. - - - Function: get-setf-method place &optional env - This function returns the setf-method for PLACE, by invoking the - definition previously recorded by `defsetf' or - `define-setf-method'. The result is a list of five values as - described above. You can use this function to build your own - `incf'-like modify macros. (Actually, it is better to use the - internal functions `cl-setf-do-modify' and `cl-setf-do-store', - which are a bit easier to use and which also do a number of - optimizations; consult the source code for the `incf' function for - a simple example.) - - The argument ENV specifies the "environment" to be passed on to - `macroexpand' if `get-setf-method' should need to expand a macro - in PLACE. It should come from an `&environment' argument to the - macro or setf-method that called `get-setf-method'. - - See also the source code for the setf-methods for `apply' and - `substring', each of which works by calling `get-setf-method' on a - simpler case, then massaging the result in various ways. - - Modern Common Lisp defines a second, independent way to specify the -`setf' behavior of a function, namely "`setf' functions" whose names -are lists `(setf NAME)' rather than symbols. For example, `(defun -(setf foo) ...)' defines the function that is used when `setf' is -applied to `foo'. This package does not currently support `setf' -functions. In particular, it is a compile-time error to use `setf' on -a form which has not already been `defsetf''d or otherwise declared; in -newer Common Lisps, this would not be an error since the function -`(setf FUNC)' might be defined later. - - -File: cl.info, Node: Variable Bindings, Next: Conditionals, Prev: Generalized Variables, Up: Control Structure - -Variable Bindings -================= - -These Lisp forms make bindings to variables and function names, -analogous to Lisp's built-in `let' form. - - *Note Modify Macros::, for the `letf' and `letf*' forms which are -also related to variable bindings. - -* Menu: - -* Dynamic Bindings:: The `progv' form -* Lexical Bindings:: `lexical-let' and lexical closures -* Function Bindings:: `flet' and `labels' -* Macro Bindings:: `macrolet' and `symbol-macrolet' - - -File: cl.info, Node: Dynamic Bindings, Next: Lexical Bindings, Prev: Variable Bindings, Up: Variable Bindings - -Dynamic Bindings ----------------- - -The standard `let' form binds variables whose names are known at -compile-time. The `progv' form provides an easy way to bind variables -whose names are computed at run-time. - - - Special Form: progv symbols values forms... - This form establishes `let'-style variable bindings on a set of - variables computed at run-time. The expressions SYMBOLS and - VALUES are evaluated, and must return lists of symbols and values, - respectively. The symbols are bound to the corresponding values - for the duration of the body FORMs. If VALUES is shorter than - SYMBOLS, the last few symbols are made unbound (as if by - `makunbound') inside the body. If SYMBOLS is shorter than VALUES, - the excess values are ignored. - - -File: cl.info, Node: Lexical Bindings, Next: Function Bindings, Prev: Dynamic Bindings, Up: Variable Bindings - -Lexical Bindings ----------------- - -The "CL" package defines the following macro which more closely follows -the Common Lisp `let' form: - - - Special Form: lexical-let (bindings...) forms... - This form is exactly like `let' except that the bindings it - establishes are purely lexical. Lexical bindings are similar to - local variables in a language like C: Only the code physically - within the body of the `lexical-let' (after macro expansion) may - refer to the bound variables. - - (setq a 5) - (defun foo (b) (+ a b)) - (let ((a 2)) (foo a)) - => 4 - (lexical-let ((a 2)) (foo a)) - => 7 - - In this example, a regular `let' binding of `a' actually makes a - temporary change to the global variable `a', so `foo' is able to - see the binding of `a' to 2. But `lexical-let' actually creates a - distinct local variable `a' for use within its body, without any - effect on the global variable of the same name. - - The most important use of lexical bindings is to create "closures". - A closure is a function object that refers to an outside lexical - variable. For example: - - (defun make-adder (n) - (lexical-let ((n n)) - (function (lambda (m) (+ n m))))) - (setq add17 (make-adder 17)) - (funcall add17 4) - => 21 - - The call `(make-adder 17)' returns a function object which adds 17 - to its argument. If `let' had been used instead of `lexical-let', - the function object would have referred to the global `n', which - would have been bound to 17 only during the call to `make-adder' - itself. - - (defun make-counter () - (lexical-let ((n 0)) - (function* (lambda (&optional (m 1)) (incf n m))))) - (setq count-1 (make-counter)) - (funcall count-1 3) - => 3 - (funcall count-1 14) - => 17 - (setq count-2 (make-counter)) - (funcall count-2 5) - => 5 - (funcall count-1 2) - => 19 - (funcall count-2) - => 6 - - Here we see that each call to `make-counter' creates a distinct - local variable `n', which serves as a private counter for the - function object that is returned. - - Closed-over lexical variables persist until the last reference to - them goes away, just like all other Lisp objects. For example, - `count-2' refers to a function object which refers to an instance - of the variable `n'; this is the only reference to that variable, - so after `(setq count-2 nil)' the garbage collector would be able - to delete this instance of `n'. Of course, if a `lexical-let' - does not actually create any closures, then the lexical variables - are free as soon as the `lexical-let' returns. - - Many closures are used only during the extent of the bindings they - refer to; these are known as "downward funargs" in Lisp parlance. - When a closure is used in this way, regular Emacs Lisp dynamic - bindings suffice and will be more efficient than `lexical-let' - closures: - - (defun add-to-list (x list) - (mapcar (function (lambda (y) (+ x y))) list)) - (add-to-list 7 '(1 2 5)) - => (8 9 12) - - Since this lambda is only used while `x' is still bound, it is not - necessary to make a true closure out of it. - - You can use `defun' or `flet' inside a `lexical-let' to create a - named closure. If several closures are created in the body of a - single `lexical-let', they all close over the same instance of the - lexical variable. - - The `lexical-let' form is an extension to Common Lisp. In true - Common Lisp, all bindings are lexical unless declared otherwise. - - - Special Form: lexical-let* (bindings...) forms... - This form is just like `lexical-let', except that the bindings are - made sequentially in the manner of `let*'. - - -File: cl.info, Node: Function Bindings, Next: Macro Bindings, Prev: Lexical Bindings, Up: Variable Bindings - -Function Bindings ------------------ - -These forms make `let'-like bindings to functions instead of variables. - - - Special Form: flet (bindings...) forms... - This form establishes `let'-style bindings on the function cells - of symbols rather than on the value cells. Each BINDING must be a - list of the form `(NAME ARGLIST FORMS...)', which defines a - function exactly as if it were a `defun*' form. The function NAME - is defined accordingly for the duration of the body of the `flet'; - then the old function definition, or lack thereof, is restored. - - While `flet' in Common Lisp establishes a lexical binding of NAME, - Emacs Lisp `flet' makes a dynamic binding. The result is that - `flet' affects indirect calls to a function as well as calls - directly inside the `flet' form itself. - - You can use `flet' to disable or modify the behavior of a function - in a temporary fashion. This will even work on Emacs primitives, - although note that some calls to primitive functions internal to - Emacs are made without going through the symbol's function cell, - and so will not be affected by `flet'. For example, - - (flet ((message (&rest args) (push args saved-msgs))) - (do-something)) - - This code attempts to replace the built-in function `message' with - a function that simply saves the messages in a list rather than - displaying them. The original definition of `message' will be - restored after `do-something' exits. This code will work fine on - messages generated by other Lisp code, but messages generated - directly inside Emacs will not be caught since they make direct - C-language calls to the message routines rather than going through - the Lisp `message' function. - - Functions defined by `flet' may use the full Common Lisp argument - notation supported by `defun*'; also, the function body is - enclosed in an implicit block as if by `defun*'. *Note Program - Structure::. - - - Special Form: labels (bindings...) forms... - The `labels' form is a synonym for `flet'. (In Common Lisp, - `labels' and `flet' differ in ways that depend on their lexical - scoping; these distinctions vanish in dynamically scoped Emacs - Lisp.) - - -File: cl.info, Node: Macro Bindings, Prev: Function Bindings, Up: Variable Bindings - -Macro Bindings --------------- - -These forms create local macros and "symbol macros." - - - Special Form: macrolet (bindings...) forms... - This form is analogous to `flet', but for macros instead of - functions. Each BINDING is a list of the same form as the - arguments to `defmacro*' (i.e., a macro name, argument list, and - macro-expander forms). The macro is defined accordingly for use - within the body of the `macrolet'. - - Because of the nature of macros, `macrolet' is lexically scoped - even in Emacs Lisp: The `macrolet' binding will affect only calls - that appear physically within the body FORMS, possibly after - expansion of other macros in the body. - - - Special Form: symbol-macrolet (bindings...) forms... - This form creates "symbol macros", which are macros that look like - variable references rather than function calls. Each BINDING is a - list `(VAR EXPANSION)'; any reference to VAR within the body FORMS - is replaced by EXPANSION. - - (setq bar '(5 . 9)) - (symbol-macrolet ((foo (car bar))) - (incf foo)) - bar - => (6 . 9) - - A `setq' of a symbol macro is treated the same as a `setf'. I.e., - `(setq foo 4)' in the above would be equivalent to `(setf foo 4)', - which in turn expands to `(setf (car bar) 4)'. - - Likewise, a `let' or `let*' binding a symbol macro is treated like - a `letf' or `letf*'. This differs from true Common Lisp, where - the rules of lexical scoping cause a `let' binding to shadow a - `symbol-macrolet' binding. In this package, only `lexical-let' - and `lexical-let*' will shadow a symbol macro. - - There is no analogue of `defmacro' for symbol macros; all symbol - macros are local. A typical use of `symbol-macrolet' is in the - expansion of another macro: - - (defmacro* my-dolist ((x list) &rest body) - (let ((var (gensym))) - (list 'loop 'for var 'on list 'do - (list* 'symbol-macrolet (list (list x (list 'car var))) - body)))) - - (setq mylist '(1 2 3 4)) - (my-dolist (x mylist) (incf x)) - mylist - => (2 3 4 5) - - In this example, the `my-dolist' macro is similar to `dolist' - (*note Iteration::) except that the variable `x' becomes a true - reference onto the elements of the list. The `my-dolist' call - shown here expands to - - (loop for G1234 on mylist do - (symbol-macrolet ((x (car G1234))) - (incf x))) - - which in turn expands to - - (loop for G1234 on mylist do (incf (car G1234))) - - *Note Loop Facility::, for a description of the `loop' macro. - This package defines a nonstandard `in-ref' loop clause that works - much like `my-dolist'. - - -File: cl.info, Node: Conditionals, Next: Blocks and Exits, Prev: Variable Bindings, Up: Control Structure - -Conditionals -============ - -These conditional forms augment Emacs Lisp's simple `if', `and', `or', -and `cond' forms. - - - Special Form: when test forms... - This is a variant of `if' where there are no "else" forms, and - possibly several "then" forms. In particular, - - (when TEST A B C) - - is entirely equivalent to - - (if TEST (progn A B C) nil) - - - Special Form: unless test forms... - This is a variant of `if' where there are no "then" forms, and - possibly several "else" forms: - - (unless TEST A B C) - - is entirely equivalent to - - (when (not TEST) A B C) - - - Special Form: case keyform clause... - This macro evaluates KEYFORM, then compares it with the key values - listed in the various CLAUSEs. Whichever clause matches the key - is executed; comparison is done by `eql'. If no clause matches, - the `case' form returns `nil'. The clauses are of the form - - (KEYLIST BODY-FORMS...) - - where KEYLIST is a list of key values. If there is exactly one - value, and it is not a cons cell or the symbol `nil' or `t', then - it can be used by itself as a KEYLIST without being enclosed in a - list. All key values in the `case' form must be distinct. The - final clauses may use `t' in place of a KEYLIST to indicate a - default clause that should be taken if none of the other clauses - match. (The symbol `otherwise' is also recognized in place of - `t'. To make a clause that matches the actual symbol `t', `nil', - or `otherwise', enclose the symbol in a list.) - - For example, this expression reads a keystroke, then does one of - four things depending on whether it is an `a', a `b', a or - , or anything else. - - (case (read-char) - (?a (do-a-thing)) - (?b (do-b-thing)) - ((?\r ?\n) (do-ret-thing)) - (t (do-other-thing))) - - - Special Form: ecase keyform clause... - This macro is just like `case', except that if the key does not - match any of the clauses, an error is signalled rather than simply - returning `nil'. - - - Special Form: typecase keyform clause... - This macro is a version of `case' that checks for types rather - than values. Each CLAUSE is of the form `(TYPE BODY...)'. *Note - Type Predicates::, for a description of type specifiers. For - example, - - (typecase x - (integer (munch-integer x)) - (float (munch-float x)) - (string (munch-integer (string-to-int x))) - (t (munch-anything x))) - - The type specifier `t' matches any type of object; the word - `otherwise' is also allowed. To make one clause match any of - several types, use an `(or ...)' type specifier. - - - Special Form: etypecase keyform clause... - This macro is just like `typecase', except that if the key does - not match any of the clauses, an error is signalled rather than - simply returning `nil'. - - -File: cl.info, Node: Blocks and Exits, Next: Iteration, Prev: Conditionals, Up: Control Structure - -Blocks and Exits -================ - -Common Lisp "blocks" provide a non-local exit mechanism very similar to -`catch' and `throw', but lexically rather than dynamically scoped. -This package actually implements `block' in terms of `catch'; however, -the lexical scoping allows the optimizing byte-compiler to omit the -costly `catch' step if the body of the block does not actually -`return-from' the block. - - - Special Form: block name forms... - The FORMS are evaluated as if by a `progn'. However, if any of - the FORMS execute `(return-from NAME)', they will jump out and - return directly from the `block' form. The `block' returns the - result of the last FORM unless a `return-from' occurs. - - The `block'/`return-from' mechanism is quite similar to the - `catch'/`throw' mechanism. The main differences are that block - NAMEs are unevaluated symbols, rather than forms (such as quoted - symbols) which evaluate to a tag at run-time; and also that blocks - are lexically scoped whereas `catch'/`throw' are dynamically - scoped. This means that functions called from the body of a - `catch' can also `throw' to the `catch', but the `return-from' - referring to a block name must appear physically within the FORMS - that make up the body of the block. They may not appear within - other called functions, although they may appear within macro - expansions or `lambda's in the body. Block names and `catch' - names form independent name-spaces. - - In true Common Lisp, `defun' and `defmacro' surround the function - or expander bodies with implicit blocks with the same name as the - function or macro. This does not occur in Emacs Lisp, but this - package provides `defun*' and `defmacro*' forms which do create - the implicit block. - - The Common Lisp looping constructs defined by this package, such - as `loop' and `dolist', also create implicit blocks just as in - Common Lisp. - - Because they are implemented in terms of Emacs Lisp `catch' and - `throw', blocks have the same overhead as actual `catch' - constructs (roughly two function calls). However, Zawinski and - Furuseth's optimizing byte compiler (standard in Emacs 19) will - optimize away the `catch' if the block does not in fact contain - any `return' or `return-from' calls that jump to it. This means - that `do' loops and `defun*' functions which don't use `return' - don't pay the overhead to support it. - - - Special Form: return-from name [result] - This macro returns from the block named NAME, which must be an - (unevaluated) symbol. If a RESULT form is specified, it is - evaluated to produce the result returned from the `block'. - Otherwise, `nil' is returned. - - - Special Form: return [result] - This macro is exactly like `(return-from nil RESULT)'. Common - Lisp loops like `do' and `dolist' implicitly enclose themselves in - `nil' blocks. - - -File: cl.info, Node: Iteration, Next: Loop Facility, Prev: Blocks and Exits, Up: Control Structure - -Iteration -========= - -The macros described here provide more sophisticated, high-level -looping constructs to complement Emacs Lisp's basic `while' loop. - - - Special Form: loop forms... - The "CL" package supports both the simple, old-style meaning of - `loop' and the extremely powerful and flexible feature known as - the "Loop Facility" or "Loop Macro". This more advanced facility - is discussed in the following section; *note Loop Facility::. The - simple form of `loop' is described here. - - If `loop' is followed by zero or more Lisp expressions, then - `(loop EXPRS...)' simply creates an infinite loop executing the - expressions over and over. The loop is enclosed in an implicit - `nil' block. Thus, - - (loop (foo) (if (no-more) (return 72)) (bar)) - - is exactly equivalent to - - (block nil (while t (foo) (if (no-more) (return 72)) (bar))) - - If any of the expressions are plain symbols, the loop is instead - interpreted as a Loop Macro specification as described later. - (This is not a restriction in practice, since a plain symbol in - the above notation would simply access and throw away the value of - a variable.) - - - Special Form: do (spec...) (end-test [result...]) forms... - This macro creates a general iterative loop. Each SPEC is of the - form - - (VAR [INIT [STEP]]) - - The loop works as follows: First, each VAR is bound to the - associated INIT value as if by a `let' form. Then, in each - iteration of the loop, the END-TEST is evaluated; if true, the - loop is finished. Otherwise, the body FORMS are evaluated, then - each VAR is set to the associated STEP expression (as if by a - `psetq' form) and the next iteration begins. Once the END-TEST - becomes true, the RESULT forms are evaluated (with the VARs still - bound to their values) to produce the result returned by `do'. - - The entire `do' loop is enclosed in an implicit `nil' block, so - that you can use `(return)' to break out of the loop at any time. - - If there are no RESULT forms, the loop returns `nil'. If a given - VAR has no STEP form, it is bound to its INIT value but not - otherwise modified during the `do' loop (unless the code - explicitly modifies it); this case is just a shorthand for putting - a `(let ((VAR INIT)) ...)' around the loop. If INIT is also - omitted it defaults to `nil', and in this case a plain `VAR' can - be used in place of `(VAR)', again following the analogy with - `let'. - - This example (from Steele) illustrates a loop which applies the - function `f' to successive pairs of values from the lists `foo' - and `bar'; it is equivalent to the call `(mapcar* 'f foo bar)'. - Note that this loop has no body FORMS at all, performing all its - work as side effects of the rest of the loop. - - (do ((x foo (cdr x)) - (y bar (cdr y)) - (z nil (cons (f (car x) (car y)) z))) - ((or (null x) (null y)) - (nreverse z))) - - - Special Form: do* (spec...) (end-test [result...]) forms... - This is to `do' what `let*' is to `let'. In particular, the - initial values are bound as if by `let*' rather than `let', and - the steps are assigned as if by `setq' rather than `psetq'. - - Here is another way to write the above loop: - - (do* ((xp foo (cdr xp)) - (yp bar (cdr yp)) - (x (car xp) (car xp)) - (y (car yp) (car yp)) - z) - ((or (null xp) (null yp)) - (nreverse z)) - (push (f x y) z)) - - - Special Form: dolist (var list [result]) forms... - This is a more specialized loop which iterates across the elements - of a list. LIST should evaluate to a list; the body FORMS are - executed with VAR bound to each element of the list in turn. - Finally, the RESULT form (or `nil') is evaluated with VAR bound to - `nil' to produce the result returned by the loop. The loop is - surrounded by an implicit `nil' block. - - - Special Form: dotimes (var count [result]) forms... - This is a more specialized loop which iterates a specified number - of times. The body is executed with VAR bound to the integers - from zero (inclusive) to COUNT (exclusive), in turn. Then the - `result' form is evaluated with VAR bound to the total number of - iterations that were done (i.e., `(max 0 COUNT)') to get the - return value for the loop form. The loop is surrounded by an - implicit `nil' block. - - - Special Form: do-symbols (var [obarray [result]]) forms... - This loop iterates over all interned symbols. If OBARRAY is - specified and is not `nil', it loops over all symbols in that - obarray. For each symbol, the body FORMS are evaluated with VAR - bound to that symbol. The symbols are visited in an unspecified - order. Afterward the RESULT form, if any, is evaluated (with VAR - bound to `nil') to get the return value. The loop is surrounded - by an implicit `nil' block. - - - Special Form: do-all-symbols (var [result]) forms... - This is identical to `do-symbols' except that the OBARRAY argument - is omitted; it always iterates over the default obarray. - - *Note Mapping over Sequences::, for some more functions for -iterating over vectors or lists. - - -File: cl.info, Node: Loop Facility, Next: Multiple Values, Prev: Iteration, Up: Control Structure - -Loop Facility -============= - -A common complaint with Lisp's traditional looping constructs is that -they are either too simple and limited, such as Common Lisp's `dotimes' -or Emacs Lisp's `while', or too unreadable and obscure, like Common -Lisp's `do' loop. - - To remedy this, recent versions of Common Lisp have added a new -construct called the "Loop Facility" or "`loop' macro," with an -easy-to-use but very powerful and expressive syntax. - -* Menu: - -* Loop Basics:: `loop' macro, basic clause structure -* Loop Examples:: Working examples of `loop' macro -* For Clauses:: Clauses introduced by `for' or `as' -* Iteration Clauses:: `repeat', `while', `thereis', etc. -* Accumulation Clauses:: `collect', `sum', `maximize', etc. -* Other Clauses:: `with', `if', `initially', `finally' - - -File: cl.info, Node: Loop Basics, Next: Loop Examples, Prev: Loop Facility, Up: Loop Facility - -Loop Basics ------------ - -The `loop' macro essentially creates a mini-language within Lisp that -is specially tailored for describing loops. While this language is a -little strange-looking by the standards of regular Lisp, it turns out -to be very easy to learn and well-suited to its purpose. - - Since `loop' is a macro, all parsing of the loop language takes -place at byte-compile time; compiled `loop's are just as efficient as -the equivalent `while' loops written longhand. - - - Special Form: loop clauses... - A loop construct consists of a series of CLAUSEs, each introduced - by a symbol like `for' or `do'. Clauses are simply strung - together in the argument list of `loop', with minimal extra - parentheses. The various types of clauses specify - initializations, such as the binding of temporary variables, - actions to be taken in the loop, stepping actions, and final - cleanup. - - Common Lisp specifies a certain general order of clauses in a loop: - - (loop NAME-CLAUSE - VAR-CLAUSES... - ACTION-CLAUSES...) - - The NAME-CLAUSE optionally gives a name to the implicit block that - surrounds the loop. By default, the implicit block is named - `nil'. The VAR-CLAUSES specify what variables should be bound - during the loop, and how they should be modified or iterated - throughout the course of the loop. The ACTION-CLAUSES are things - to be done during the loop, such as computing, collecting, and - returning values. - - The Emacs version of the `loop' macro is less restrictive about - the order of clauses, but things will behave most predictably if - you put the variable-binding clauses `with', `for', and `repeat' - before the action clauses. As in Common Lisp, `initially' and - `finally' clauses can go anywhere. - - Loops generally return `nil' by default, but you can cause them to - return a value by using an accumulation clause like `collect', an - end-test clause like `always', or an explicit `return' clause to - jump out of the implicit block. (Because the loop body is - enclosed in an implicit block, you can also use regular Lisp - `return' or `return-from' to break out of the loop.) - - The following sections give some examples of the Loop Macro in -action, and describe the particular loop clauses in great detail. -Consult the second edition of Steele's "Common Lisp, the Language", for -additional discussion and examples of the `loop' macro. - - -File: cl.info, Node: Loop Examples, Next: For Clauses, Prev: Loop Basics, Up: Loop Facility - -Loop Examples -------------- - -Before listing the full set of clauses that are allowed, let's look at -a few example loops just to get a feel for the `loop' language. - - (loop for buf in (buffer-list) - collect (buffer-file-name buf)) - -This loop iterates over all Emacs buffers, using the list returned by -`buffer-list'. For each buffer `buf', it calls `buffer-file-name' and -collects the results into a list, which is then returned from the -`loop' construct. The result is a list of the file names of all the -buffers in Emacs' memory. The words `for', `in', and `collect' are -reserved words in the `loop' language. - - (loop repeat 20 do (insert "Yowsa\n")) - -This loop inserts the phrase "Yowsa" twenty times in the current buffer. - - (loop until (eobp) do (munch-line) (forward-line 1)) - -This loop calls `munch-line' on every line until the end of the buffer. -If point is already at the end of the buffer, the loop exits -immediately. - - (loop do (munch-line) until (eobp) do (forward-line 1)) - -This loop is similar to the above one, except that `munch-line' is -always called at least once. - - (loop for x from 1 to 100 - for y = (* x x) - until (>= y 729) - finally return (list x (= y 729))) - -This more complicated loop searches for a number `x' whose square is -729. For safety's sake it only examines `x' values up to 100; dropping -the phrase `to 100' would cause the loop to count upwards with no -limit. The second `for' clause defines `y' to be the square of `x' -within the loop; the expression after the `=' sign is reevaluated each -time through the loop. The `until' clause gives a condition for -terminating the loop, and the `finally' clause says what to do when the -loop finishes. (This particular example was written less concisely -than it could have been, just for the sake of illustration.) - - Note that even though this loop contains three clauses (two `for's -and an `until') that would have been enough to define loops all by -themselves, it still creates a single loop rather than some sort of -triple-nested loop. You must explicitly nest your `loop' constructs if -you want nested loops. - diff -u -r -N xemacs-21.4.14/info/cl.info-3 xemacs-21.4.15/info/cl.info-3 --- xemacs-21.4.14/info/cl.info-3 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-3 1969-12-31 19:00:00.000000000 -0500 @@ -1,1125 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: For Clauses, Next: Iteration Clauses, Prev: Loop Examples, Up: Loop Facility - -For Clauses ------------ - -Most loops are governed by one or more `for' clauses. A `for' clause -simultaneously describes variables to be bound, how those variables are -to be stepped during the loop, and usually an end condition based on -those variables. - - The word `as' is a synonym for the word `for'. This word is -followed by a variable name, then a word like `from' or `across' that -describes the kind of iteration desired. In Common Lisp, the phrase -`being the' sometimes precedes the type of iteration; in this package -both `being' and `the' are optional. The word `each' is a synonym for -`the', and the word that follows it may be singular or plural: `for x -being the elements of y' or `for x being each element of y'. Which -form you use is purely a matter of style. - - The variable is bound around the loop as if by `let': - - (setq i 'happy) - (loop for i from 1 to 10 do (do-something-with i)) - i - => happy - -`for VAR from EXPR1 to EXPR2 by EXPR3' - This type of `for' clause creates a counting loop. Each of the - three sub-terms is optional, though there must be at least one - term so that the clause is marked as a counting clause. - - The three expressions are the starting value, the ending value, and - the step value, respectively, of the variable. The loop counts - upwards by default (EXPR3 must be positive), from EXPR1 to EXPR2 - inclusively. If you omit the `from' term, the loop counts from - zero; if you omit the `to' term, the loop counts forever without - stopping (unless stopped by some other loop clause, of course); if - you omit the `by' term, the loop counts in steps of one. - - You can replace the word `from' with `upfrom' or `downfrom' to - indicate the direction of the loop. Likewise, you can replace - `to' with `upto' or `downto'. For example, `for x from 5 downto - 1' executes five times with `x' taking on the integers from 5 down - to 1 in turn. Also, you can replace `to' with `below' or `above', - which are like `upto' and `downto' respectively except that they - are exclusive rather than inclusive limits: - - (loop for x to 10 collect x) - => (0 1 2 3 4 5 6 7 8 9 10) - (loop for x below 10 collect x) - => (0 1 2 3 4 5 6 7 8 9) - - The `by' value is always positive, even for downward-counting - loops. Some sort of `from' value is required for downward loops; - `for x downto 5' is not a legal loop clause all by itself. - -`for VAR in LIST by FUNCTION' - This clause iterates VAR over all the elements of LIST, in turn. - If you specify the `by' term, then FUNCTION is used to traverse - the list instead of `cdr'; it must be a function taking one - argument. For example: - - (loop for x in '(1 2 3 4 5 6) collect (* x x)) - => (1 4 9 16 25 36) - (loop for x in '(1 2 3 4 5 6) by 'cddr collect (* x x)) - => (1 9 25) - -`for VAR on LIST by FUNCTION' - This clause iterates VAR over all the cons cells of LIST. - - (loop for x on '(1 2 3 4) collect x) - => ((1 2 3 4) (2 3 4) (3 4) (4)) - - With `by', there is no real reason that the `on' expression must - be a list. For example: - - (loop for x on first-animal by 'next-animal collect x) - - where `(next-animal x)' takes an "animal" X and returns the next - in the (assumed) sequence of animals, or `nil' if X was the last - animal in the sequence. - -`for VAR in-ref LIST by FUNCTION' - This is like a regular `in' clause, but VAR becomes a `setf'-able - "reference" onto the elements of the list rather than just a - temporary variable. For example, - - (loop for x in-ref my-list do (incf x)) - - increments every element of `my-list' in place. This clause is an - extension to standard Common Lisp. - -`for VAR across ARRAY' - This clause iterates VAR over all the elements of ARRAY, which may - be a vector or a string. - - (loop for x across "aeiou" - do (use-vowel (char-to-string x))) - -`for VAR across-ref ARRAY' - This clause iterates over an array, with VAR a `setf'-able - reference onto the elements; see `in-ref' above. - -`for VAR being the elements of SEQUENCE' - This clause iterates over the elements of SEQUENCE, which may be a - list, vector, or string. Since the type must be determined at - run-time, this is somewhat less efficient than `in' or `across'. - The clause may be followed by the additional term `using (index - VAR2)' to cause VAR2 to be bound to the successive indices - (starting at 0) of the elements. - - This clause type is taken from older versions of the `loop' macro, - and is not present in modern Common Lisp. The `using (sequence - ...)' term of the older macros is not supported. - -`for VAR being the elements of-ref SEQUENCE' - This clause iterates over a sequence, with VAR a `setf'-able - reference onto the elements; see `in-ref' above. - -`for VAR being the symbols [of OBARRAY]' - This clause iterates over symbols, either over all interned symbols - or over all symbols in OBARRAY. The loop is executed with VAR - bound to each symbol in turn. The symbols are visited in an - unspecified order. - - As an example, - - (loop for sym being the symbols - when (fboundp sym) - when (string-match "^map" (symbol-name sym)) - collect sym) - - returns a list of all the functions whose names begin with `map'. - - The Common Lisp words `external-symbols' and `present-symbols' are - also recognized but are equivalent to `symbols' in Emacs Lisp. - - Due to a minor implementation restriction, it will not work to have - more than one `for' clause iterating over symbols, hash tables, - keymaps, overlays, or intervals in a given `loop'. Fortunately, - it would rarely if ever be useful to do so. It _is_ legal to mix - one of these types of clauses with other clauses like `for ... to' - or `while'. - -`for VAR being the hash-keys of HASH-TABLE' - This clause iterates over the entries in HASH-TABLE. For each - hash table entry, VAR is bound to the entry's key. If you write - `the hash-values' instead, VAR is bound to the values of the - entries. The clause may be followed by the additional term `using - (hash-values VAR2)' (where `hash-values' is the opposite word of - the word following `the') to cause VAR and VAR2 to be bound to the - two parts of each hash table entry. - -`for VAR being the key-codes of KEYMAP' - This clause iterates over the entries in KEYMAP. In GNU Emacs 18 - and 19, keymaps are either alists or vectors, and key-codes are - integers or symbols. In XEmacs, keymaps are a special new data - type, and key-codes are symbols or lists of symbols. The - iteration does not enter nested keymaps or inherited (parent) - keymaps. You can use `the key-bindings' to access the commands - bound to the keys rather than the key codes, and you can add a - `using' clause to access both the codes and the bindings together. - -`for VAR being the key-seqs of KEYMAP' - This clause iterates over all key sequences defined by KEYMAP and - its nested keymaps, where VAR takes on values which are strings in - Emacs 18 or vectors in Emacs 19. The strings or vectors are - reused for each iteration, so you must copy them if you wish to - keep them permanently. You can add a `using (key-bindings ...)' - clause to get the command bindings as well. - -`for VAR being the overlays [of BUFFER] ...' - This clause iterates over the Emacs 19 "overlays" or XEmacs - "extents" of a buffer (the clause `extents' is synonymous with - `overlays'). Under Emacs 18, this clause iterates zero times. If - the `of' term is omitted, the current buffer is used. This clause - also accepts optional `from POS' and `to POS' terms, limiting the - clause to overlays which overlap the specified region. - -`for VAR being the intervals [of BUFFER] ...' - This clause iterates over all intervals of a buffer with constant - text properties. The variable VAR will be bound to conses of - start and end positions, where one start position is always equal - to the previous end position. The clause allows `of', `from', - `to', and `property' terms, where the latter term restricts the - search to just the specified property. The `of' term may specify - either a buffer or a string. This clause is useful only in GNU - Emacs 19; in other versions, all buffers and strings consist of a - single interval. - -`for VAR being the frames' - This clause iterates over all frames, i.e., X window system windows - open on Emacs files. This clause works only under Emacs 19. The - clause `screens' is a synonym for `frames'. The frames are - visited in `next-frame' order starting from `selected-frame'. - -`for VAR being the windows [of FRAME]' - This clause iterates over the windows (in the Emacs sense) of the - current frame, or of the specified FRAME. (In Emacs 18 there is - only ever one frame, and the `of' term is not allowed there.) - -`for VAR being the buffers' - This clause iterates over all buffers in Emacs. It is equivalent - to `for VAR in (buffer-list)'. - -`for VAR = EXPR1 then EXPR2' - This clause does a general iteration. The first time through the - loop, VAR will be bound to EXPR1. On the second and successive - iterations it will be set by evaluating EXPR2 (which may refer to - the old value of VAR). For example, these two loops are - effectively the same: - - (loop for x on my-list by 'cddr do ...) - (loop for x = my-list then (cddr x) while x do ...) - - Note that this type of `for' clause does not imply any sort of - terminating condition; the above example combines it with a - `while' clause to tell when to end the loop. - - If you omit the `then' term, EXPR1 is used both for the initial - setting and for successive settings: - - (loop for x = (random) when (> x 0) return x) - - This loop keeps taking random numbers from the `(random)' function - until it gets a positive one, which it then returns. - - If you include several `for' clauses in a row, they are treated -sequentially (as if by `let*' and `setq'). You can instead use the -word `and' to link the clauses, in which case they are processed in -parallel (as if by `let' and `psetq'). - - (loop for x below 5 for y = nil then x collect (list x y)) - => ((0 nil) (1 1) (2 2) (3 3) (4 4)) - (loop for x below 5 and y = nil then x collect (list x y)) - => ((0 nil) (1 0) (2 1) (3 2) (4 3)) - -In the first loop, `y' is set based on the value of `x' that was just -set by the previous clause; in the second loop, `x' and `y' are set -simultaneously so `y' is set based on the value of `x' left over from -the previous time through the loop. - - Another feature of the `loop' macro is "destructuring", similar in -concept to the destructuring provided by `defmacro'. The VAR part of -any `for' clause can be given as a list of variables instead of a -single variable. The values produced during loop execution must be -lists; the values in the lists are stored in the corresponding -variables. - - (loop for (x y) in '((2 3) (4 5) (6 7)) collect (+ x y)) - => (5 9 13) - - In loop destructuring, if there are more values than variables the -trailing values are ignored, and if there are more variables than -values the trailing variables get the value `nil'. If `nil' is used as -a variable name, the corresponding values are ignored. Destructuring -may be nested, and dotted lists of variables like `(x . y)' are allowed. - - -File: cl.info, Node: Iteration Clauses, Next: Accumulation Clauses, Prev: For Clauses, Up: Loop Facility - -Iteration Clauses ------------------ - -Aside from `for' clauses, there are several other loop clauses that -control the way the loop operates. They might be used by themselves, -or in conjunction with one or more `for' clauses. - -`repeat INTEGER' - This clause simply counts up to the specified number using an - internal temporary variable. The loops - - (loop repeat n do ...) - (loop for temp to n do ...) - - are identical except that the second one forces you to choose a - name for a variable you aren't actually going to use. - -`while CONDITION' - This clause stops the loop when the specified condition (any Lisp - expression) becomes `nil'. For example, the following two loops - are equivalent, except for the implicit `nil' block that surrounds - the second one: - - (while COND FORMS...) - (loop while COND do FORMS...) - -`until CONDITION' - This clause stops the loop when the specified condition is true, - i.e., non-`nil'. - -`always CONDITION' - This clause stops the loop when the specified condition is `nil'. - Unlike `while', it stops the loop using `return nil' so that the - `finally' clauses are not executed. If all the conditions were - non-`nil', the loop returns `t': - - (if (loop for size in size-list always (> size 10)) - (some-big-sizes) - (no-big-sizes)) - -`never CONDITION' - This clause is like `always', except that the loop returns `t' if - any conditions were false, or `nil' otherwise. - -`thereis CONDITION' - This clause stops the loop when the specified form is non-`nil'; - in this case, it returns that non-`nil' value. If all the values - were `nil', the loop returns `nil'. - - -File: cl.info, Node: Accumulation Clauses, Next: Other Clauses, Prev: Iteration Clauses, Up: Loop Facility - -Accumulation Clauses --------------------- - -These clauses cause the loop to accumulate information about the -specified Lisp FORM. The accumulated result is returned from the loop -unless overridden, say, by a `return' clause. - -`collect FORM' - This clause collects the values of FORM into a list. Several - examples of `collect' appear elsewhere in this manual. - - The word `collecting' is a synonym for `collect', and likewise for - the other accumulation clauses. - -`append FORM' - This clause collects lists of values into a result list using - `append'. - -`nconc FORM' - This clause collects lists of values into a result list by - destructively modifying the lists rather than copying them. - -`concat FORM' - This clause concatenates the values of the specified FORM into a - string. (It and the following clause are extensions to standard - Common Lisp.) - -`vconcat FORM' - This clause concatenates the values of the specified FORM into a - vector. - -`count FORM' - This clause counts the number of times the specified FORM - evaluates to a non-`nil' value. - -`sum FORM' - This clause accumulates the sum of the values of the specified - FORM, which must evaluate to a number. - -`maximize FORM' - This clause accumulates the maximum value of the specified FORM, - which must evaluate to a number. The return value is undefined if - `maximize' is executed zero times. - -`minimize FORM' - This clause accumulates the minimum value of the specified FORM. - - Accumulation clauses can be followed by `into VAR' to cause the data -to be collected into variable VAR (which is automatically `let'-bound -during the loop) rather than an unnamed temporary variable. Also, -`into' accumulations do not automatically imply a return value. The -loop must use some explicit mechanism, such as `finally return', to -return the accumulated result. - - It is legal for several accumulation clauses of the same type to -accumulate into the same place. From Steele: - - (loop for name in '(fred sue alice joe june) - for kids in '((bob ken) () () (kris sunshine) ()) - collect name - append kids) - => (fred bob ken sue alice joe kris sunshine june) - - -File: cl.info, Node: Other Clauses, Prev: Accumulation Clauses, Up: Loop Facility - -Other Clauses -------------- - -This section describes the remaining loop clauses. - -`with VAR = VALUE' - This clause binds a variable to a value around the loop, but - otherwise leaves the variable alone during the loop. The following - loops are basically equivalent: - - (loop with x = 17 do ...) - (let ((x 17)) (loop do ...)) - (loop for x = 17 then x do ...) - - Naturally, the variable VAR might be used for some purpose in the - rest of the loop. For example: - - (loop for x in my-list with res = nil do (push x res) - finally return res) - - This loop inserts the elements of `my-list' at the front of a new - list being accumulated in `res', then returns the list `res' at - the end of the loop. The effect is similar to that of a `collect' - clause, but the list gets reversed by virtue of the fact that - elements are being pushed onto the front of `res' rather than the - end. - - If you omit the `=' term, the variable is initialized to `nil'. - (Thus the `= nil' in the above example is unnecessary.) - - Bindings made by `with' are sequential by default, as if by - `let*'. Just like `for' clauses, `with' clauses can be linked - with `and' to cause the bindings to be made by `let' instead. - -`if CONDITION CLAUSE' - This clause executes the following loop clause only if the - specified condition is true. The following CLAUSE should be an - accumulation, `do', `return', `if', or `unless' clause. Several - clauses may be linked by separating them with `and'. These - clauses may be followed by `else' and a clause or clauses to - execute if the condition was false. The whole construct may - optionally be followed by the word `end' (which may be used to - disambiguate an `else' or `and' in a nested `if'). - - The actual non-`nil' value of the condition form is available by - the name `it' in the "then" part. For example: - - (setq funny-numbers '(6 13 -1)) - => (6 13 -1) - (loop for x below 10 - if (oddp x) - collect x into odds - and if (memq x funny-numbers) return (cdr it) end - else - collect x into evens - finally return (vector odds evens)) - => [(1 3 5 7 9) (0 2 4 6 8)] - (setq funny-numbers '(6 7 13 -1)) - => (6 7 13 -1) - (loop ) - => (13 -1) - - Note the use of `and' to put two clauses into the "then" part, one - of which is itself an `if' clause. Note also that `end', while - normally optional, was necessary here to make it clear that the - `else' refers to the outermost `if' clause. In the first case, - the loop returns a vector of lists of the odd and even values of - X. In the second case, the odd number 7 is one of the - `funny-numbers' so the loop returns early; the actual returned - value is based on the result of the `memq' call. - -`when CONDITION CLAUSE' - This clause is just a synonym for `if'. - -`unless CONDITION CLAUSE' - The `unless' clause is just like `if' except that the sense of the - condition is reversed. - -`named NAME' - This clause gives a name other than `nil' to the implicit block - surrounding the loop. The NAME is the symbol to be used as the - block name. - -`initially [do] FORMS...' - This keyword introduces one or more Lisp forms which will be - executed before the loop itself begins (but after any variables - requested by `for' or `with' have been bound to their initial - values). `initially' clauses can appear anywhere; if there are - several, they are executed in the order they appear in the loop. - The keyword `do' is optional. - -`finally [do] FORMS...' - This introduces Lisp forms which will be executed after the loop - finishes (say, on request of a `for' or `while'). `initially' and - `finally' clauses may appear anywhere in the loop construct, but - they are executed (in the specified order) at the beginning or - end, respectively, of the loop. - -`finally return FORM' - This says that FORM should be executed after the loop is done to - obtain a return value. (Without this, or some other clause like - `collect' or `return', the loop will simply return `nil'.) - Variables bound by `for', `with', or `into' will still contain - their final values when FORM is executed. - -`do FORMS...' - The word `do' may be followed by any number of Lisp expressions - which are executed as an implicit `progn' in the body of the loop. - Many of the examples in this section illustrate the use of `do'. - -`return FORM' - This clause causes the loop to return immediately. The following - Lisp form is evaluated to give the return value of the `loop' - form. The `finally' clauses, if any, are not executed. Of - course, `return' is generally used inside an `if' or `unless', as - its use in a top-level loop clause would mean the loop would never - get to "loop" more than once. - - The clause `return FORM' is equivalent to `do (return FORM)' (or - `return-from' if the loop was named). The `return' clause is - implemented a bit more efficiently, though. - - While there is no high-level way to add user extensions to `loop' -(comparable to `defsetf' for `setf', say), this package does offer two -properties called `cl-loop-handler' and `cl-loop-for-handler' which are -functions to be called when a given symbol is encountered as a -top-level loop clause or `for' clause, respectively. Consult the -source code in file `cl-macs.el' for details. - - This package's `loop' macro is compatible with that of Common Lisp, -except that a few features are not implemented: `loop-finish' and -data-type specifiers. Naturally, the `for' clauses which iterate over -keymaps, overlays, intervals, frames, windows, and buffers are -Emacs-specific extensions. - - -File: cl.info, Node: Multiple Values, Prev: Loop Facility, Up: Control Structure - -Multiple Values -=============== - -Common Lisp functions can return zero or more results. Emacs Lisp -functions, by contrast, always return exactly one result. This package -makes no attempt to emulate Common Lisp multiple return values; Emacs -versions of Common Lisp functions that return more than one value -either return just the first value (as in `compiler-macroexpand') or -return a list of values (as in `get-setf-method'). This package _does_ -define placeholders for the Common Lisp functions that work with -multiple values, but in Emacs Lisp these functions simply operate on -lists instead. The `values' form, for example, is a synonym for `list' -in Emacs. - - - Special Form: multiple-value-bind (var...) values-form forms... - This form evaluates VALUES-FORM, which must return a list of - values. It then binds the VARs to these respective values, as if - by `let', and then executes the body FORMS. If there are more - VARs than values, the extra VARs are bound to `nil'. If there are - fewer VARs than values, the excess values are ignored. - - - Special Form: multiple-value-setq (var...) form - This form evaluates FORM, which must return a list of values. It - then sets the VARs to these respective values, as if by `setq'. - Extra VARs or values are treated the same as in - `multiple-value-bind'. - - The older Quiroz package attempted a more faithful (but still -imperfect) emulation of Common Lisp multiple values. The old method -"usually" simulated true multiple values quite well, but under certain -circumstances would leave spurious return values in memory where a -later, unrelated `multiple-value-bind' form would see them. - - Since a perfect emulation is not feasible in Emacs Lisp, this -package opts to keep it as simple and predictable as possible. - - -File: cl.info, Node: Macros, Next: Declarations, Prev: Control Structure, Up: Top - -Macros -****** - -This package implements the various Common Lisp features of `defmacro', -such as destructuring, `&environment', and `&body'. Top-level `&whole' -is not implemented for `defmacro' due to technical difficulties. *Note -Argument Lists::. - - Destructuring is made available to the user by way of the following -macro: - - - Special Form: destructuring-bind arglist expr forms... - This macro expands to code which executes FORMS, with the - variables in ARGLIST bound to the list of values returned by EXPR. - The ARGLIST can include all the features allowed for `defmacro' - argument lists, including destructuring. (The `&environment' - keyword is not allowed.) The macro expansion will signal an error - if EXPR returns a list of the wrong number of arguments or with - incorrect keyword arguments. - - This package also includes the Common Lisp `define-compiler-macro' -facility, which allows you to define compile-time expansions and -optimizations for your functions. - - - Special Form: define-compiler-macro name arglist forms... - This form is similar to `defmacro', except that it only expands - calls to NAME at compile-time; calls processed by the Lisp - interpreter are not expanded, nor are they expanded by the - `macroexpand' function. - - The argument list may begin with a `&whole' keyword and a - variable. This variable is bound to the macro-call form itself, - i.e., to a list of the form `(NAME ARGS...)'. If the macro - expander returns this form unchanged, then the compiler treats it - as a normal function call. This allows compiler macros to work as - optimizers for special cases of a function, leaving complicated - cases alone. - - For example, here is a simplified version of a definition that - appears as a standard part of this package: - - (define-compiler-macro member* (&whole form a list &rest keys) - (if (and (null keys) - (eq (car-safe a) 'quote) - (not (floatp-safe (cadr a)))) - (list 'memq a list) - form)) - - This definition causes `(member* A LIST)' to change to a call to - the faster `memq' in the common case where A is a - non-floating-point constant; if A is anything else, or if there - are any keyword arguments in the call, then the original `member*' - call is left intact. (The actual compiler macro for `member*' - optimizes a number of other cases, including common `:test' - predicates.) - - - Function: compiler-macroexpand form - This function is analogous to `macroexpand', except that it - expands compiler macros rather than regular macros. It returns - FORM unchanged if it is not a call to a function for which a - compiler macro has been defined, or if that compiler macro decided - to punt by returning its `&whole' argument. Like `macroexpand', - it expands repeatedly until it reaches a form for which no further - expansion is possible. - - *Note Macro Bindings::, for descriptions of the `macrolet' and -`symbol-macrolet' forms for making "local" macro definitions. - - -File: cl.info, Node: Declarations, Next: Symbols, Prev: Macros, Up: Top - -Declarations -************ - -Common Lisp includes a complex and powerful "declaration" mechanism -that allows you to give the compiler special hints about the types of -data that will be stored in particular variables, and about the ways -those variables and functions will be used. This package defines -versions of all the Common Lisp declaration forms: `declare', -`locally', `proclaim', `declaim', and `the'. - - Most of the Common Lisp declarations are not currently useful in -Emacs Lisp, as the byte-code system provides little opportunity to -benefit from type information, and `special' declarations are redundant -in a fully dynamically-scoped Lisp. A few declarations are meaningful -when the optimizing Emacs 19 byte compiler is being used, however. -Under the earlier non-optimizing compiler, these declarations will -effectively be ignored. - - - Function: proclaim decl-spec - This function records a "global" declaration specified by - DECL-SPEC. Since `proclaim' is a function, DECL-SPEC is evaluated - and thus should normally be quoted. - - - Special Form: declaim decl-specs... - This macro is like `proclaim', except that it takes any number of - DECL-SPEC arguments, and the arguments are unevaluated and - unquoted. The `declaim' macro also puts an `(eval-when (compile - load eval) ...)' around the declarations so that they will be - registered at compile-time as well as at run-time. (This is vital, - since normally the declarations are meant to influence the way the - compiler treats the rest of the file that contains the `declaim' - form.) - - - Special Form: declare decl-specs... - This macro is used to make declarations within functions and other - code. Common Lisp allows declarations in various locations, - generally at the beginning of any of the many "implicit `progn's" - throughout Lisp syntax, such as function bodies, `let' bodies, - etc. Currently the only declaration understood by `declare' is - `special'. - - - Special Form: locally declarations... forms... - In this package, `locally' is no different from `progn'. - - - Special Form: the type form - Type information provided by `the' is ignored in this package; in - other words, `(the TYPE FORM)' is equivalent to FORM. Future - versions of the optimizing byte-compiler may make use of this - information. - - For example, `mapcar' can map over both lists and arrays. It is - hard for the compiler to expand `mapcar' into an in-line loop - unless it knows whether the sequence will be a list or an array - ahead of time. With `(mapcar 'car (the vector foo))', a future - compiler would have enough information to expand the loop in-line. - For now, Emacs Lisp will treat the above code as exactly equivalent - to `(mapcar 'car foo)'. - - Each DECL-SPEC in a `proclaim', `declaim', or `declare' should be a -list beginning with a symbol that says what kind of declaration it is. -This package currently understands `special', `inline', `notinline', -`optimize', and `warn' declarations. (The `warn' declaration is an -extension of standard Common Lisp.) Other Common Lisp declarations, -such as `type' and `ftype', are silently ignored. - -`special' - Since all variables in Emacs Lisp are "special" (in the Common - Lisp sense), `special' declarations are only advisory. They - simply tell the optimizing byte compiler that the specified - variables are intentionally being referred to without being bound - in the body of the function. The compiler normally emits warnings - for such references, since they could be typographical errors for - references to local variables. - - The declaration `(declare (special VAR1 VAR2))' is equivalent to - `(defvar VAR1) (defvar VAR2)' in the optimizing compiler, or to - nothing at all in older compilers (which do not warn for non-local - references). - - In top-level contexts, it is generally better to write `(defvar - VAR)' than `(declaim (special VAR))', since `defvar' makes your - intentions clearer. But the older byte compilers can not handle - `defvar's appearing inside of functions, while `(declare (special - VAR))' takes care to work correctly with all compilers. - -`inline' - The `inline' DECL-SPEC lists one or more functions whose bodies - should be expanded "in-line" into calling functions whenever the - compiler is able to arrange for it. For example, the Common Lisp - function `cadr' is declared `inline' by this package so that the - form `(cadr X)' will expand directly into `(car (cdr X))' when it - is called in user functions, for a savings of one (relatively - expensive) function call. - - The following declarations are all equivalent. Note that the - `defsubst' form is a convenient way to define a function and - declare it inline all at once, but it is available only in Emacs - 19. - - (declaim (inline foo bar)) - (eval-when (compile load eval) (proclaim '(inline foo bar))) - (proclaim-inline foo bar) ; XEmacs only - (defsubst foo (...) ...) ; instead of defun; Emacs 19 only - - *Please note:* This declaration remains in effect after the - containing source file is done. It is correct to use it to - request that a function you have defined should be inlined, but it - is impolite to use it to request inlining of an external function. - - In Common Lisp, it is possible to use `(declare (inline ...))' - before a particular call to a function to cause just that call to - be inlined; the current byte compilers provide no way to implement - this, so `(declare (inline ...))' is currently ignored by this - package. - -`notinline' - The `notinline' declaration lists functions which should not be - inlined after all; it cancels a previous `inline' declaration. - -`optimize' - This declaration controls how much optimization is performed by - the compiler. Naturally, it is ignored by the earlier - non-optimizing compilers. - - The word `optimize' is followed by any number of lists like - `(speed 3)' or `(safety 2)'. Common Lisp defines several - optimization "qualities"; this package ignores all but `speed' and - `safety'. The value of a quality should be an integer from 0 to - 3, with 0 meaning "unimportant" and 3 meaning "very important." - The default level for both qualities is 1. - - In this package, with the Emacs 19 optimizing compiler, the - `speed' quality is tied to the `byte-compile-optimize' flag, which - is set to `nil' for `(speed 0)' and to `t' for higher settings; - and the `safety' quality is tied to the - `byte-compile-delete-errors' flag, which is set to `t' for - `(safety 3)' and to `nil' for all lower settings. (The latter - flag controls whether the compiler is allowed to optimize out code - whose only side-effect could be to signal an error, e.g., - rewriting `(progn foo bar)' to `bar' when it is not known whether - `foo' will be bound at run-time.) - - Note that even compiling with `(safety 0)', the Emacs byte-code - system provides sufficient checking to prevent real harm from - being done. For example, barring serious bugs in Emacs itself, - Emacs will not crash with a segmentation fault just because of an - error in a fully-optimized Lisp program. - - The `optimize' declaration is normally used in a top-level - `proclaim' or `declaim' in a file; Common Lisp allows it to be - used with `declare' to set the level of optimization locally for a - given form, but this will not work correctly with the current - version of the optimizing compiler. (The `declare' will set the - new optimization level, but that level will not automatically be - unset after the enclosing form is done.) - -`warn' - This declaration controls what sorts of warnings are generated by - the byte compiler. Again, only the optimizing compiler generates - warnings. The word `warn' is followed by any number of "warning - qualities," similar in form to optimization qualities. The - currently supported warning types are `redefine', `callargs', - `unresolved', and `free-vars'; in the current system, a value of 0 - will disable these warnings and any higher value will enable them. - See the documentation for the optimizing byte compiler for details. - - -File: cl.info, Node: Symbols, Next: Numbers, Prev: Declarations, Up: Top - -Symbols -******* - -This package defines several symbol-related features that were missing -from Emacs Lisp. - -* Menu: - -* Property Lists:: `getf', `remf' -* Creating Symbols:: `gensym', `gentemp' - - -File: cl.info, Node: Property Lists, Next: Creating Symbols, Prev: Symbols, Up: Symbols - -Property Lists -============== - -These functions augment the standard Emacs Lisp functions `get' and -`put' for operating on properties attached to objects. There are also -functions for working with property lists as first-class data -structures not attached to particular objects. - - - Function: getf place property &optional default - This function scans the list PLACE as if it were a property list, - i.e., a list of alternating property names and values. If an - even-numbered element of PLACE is found which is `eq' to PROPERTY, - the following odd-numbered element is returned. Otherwise, - DEFAULT is returned (or `nil' if no default is given). - - In particular, - - (get sym prop) == (getf (symbol-plist sym) prop) - - It is legal to use `getf' as a `setf' place, in which case its - PLACE argument must itself be a legal `setf' place. The DEFAULT - argument, if any, is ignored in this context. The effect is to - change (via `setcar') the value cell in the list that corresponds - to PROPERTY, or to cons a new property-value pair onto the list if - the property is not yet present. - - (put sym prop val) == (setf (getf (symbol-plist sym) prop) val) - - The `get' function is also `setf'-able. The fact that `default' - is ignored can sometimes be useful: - - (incf (get 'foo 'usage-count 0)) - - Here, symbol `foo''s `usage-count' property is incremented if it - exists, or set to 1 (an incremented 0) otherwise. - - When not used as a `setf' form, `getf' is just a regular function - and its PLACE argument can actually be any Lisp expression. - - - Special Form: remf place property - This macro removes the property-value pair for PROPERTY from the - property list stored at PLACE, which is any `setf'-able place - expression. It returns true if the property was found. Note that - if PROPERTY happens to be first on the list, this will effectively - do a `(setf PLACE (cddr PLACE))', whereas if it occurs later, this - simply uses `setcdr' to splice out the property and value cells. - - -File: cl.info, Node: Creating Symbols, Prev: Property Lists, Up: Symbols - -Creating Symbols -================ - -These functions create unique symbols, typically for use as temporary -variables. - - - Function: gensym &optional x - This function creates a new, uninterned symbol (using - `make-symbol') with a unique name. (The name of an uninterned - symbol is relevant only if the symbol is printed.) By default, - the name is generated from an increasing sequence of numbers, - `G1000', `G1001', `G1002', etc. If the optional argument X is a - string, that string is used as a prefix instead of `G'. - Uninterned symbols are used in macro expansions for temporary - variables, to ensure that their names will not conflict with - "real" variables in the user's code. - - - Variable: *gensym-counter* - This variable holds the counter used to generate `gensym' names. - It is incremented after each use by `gensym'. In Common Lisp this - is initialized with 0, but this package initializes it with a - random (time-dependent) value to avoid trouble when two files that - each used `gensym' in their compilation are loaded together. - - *XEmacs note:* As of XEmacs 21.0, an uninterned symbol remains - uninterned even after being dumped to bytecode. Older versions of - Emacs didn't distinguish the printed representation of interned - and uninterned symbols, so their names had to be treated more - carefully. - - - Function: gentemp &optional x - This function is like `gensym', except that it produces a new - _interned_ symbol. If the symbol that is generated already - exists, the function keeps incrementing the counter and trying - again until a new symbol is generated. - - The Quiroz `cl.el' package also defined a `defkeyword' form for -creating self-quoting keyword symbols. This package automatically -creates all keywords that are called for by `&key' argument specifiers, -and discourages the use of keywords as data unrelated to keyword -arguments, so the `defkeyword' form has been discontinued. - - -File: cl.info, Node: Numbers, Next: Sequences, Prev: Symbols, Up: Top - -Numbers -******* - -This section defines a few simple Common Lisp operations on numbers -which were left out of Emacs Lisp. - -* Menu: - -* Predicates on Numbers:: `plusp', `oddp', `floatp-safe', etc. -* Numerical Functions:: `abs', `expt', `floor*', etc. -* Random Numbers:: `random*', `make-random-state' -* Implementation Parameters:: `most-positive-fixnum', `most-positive-float' - - -File: cl.info, Node: Predicates on Numbers, Next: Numerical Functions, Prev: Numbers, Up: Numbers - -Predicates on Numbers -===================== - -These functions return `t' if the specified condition is true of the -numerical argument, or `nil' otherwise. - - - Function: plusp number - This predicate tests whether NUMBER is positive. It is an error - if the argument is not a number. - - - Function: minusp number - This predicate tests whether NUMBER is negative. It is an error - if the argument is not a number. - - - Function: oddp integer - This predicate tests whether INTEGER is odd. It is an error if - the argument is not an integer. - - - Function: evenp integer - This predicate tests whether INTEGER is even. It is an error if - the argument is not an integer. - - - Function: floatp-safe object - This predicate tests whether OBJECT is a floating-point number. - On systems that support floating-point, this is equivalent to - `floatp'. On other systems, this always returns `nil'. - - -File: cl.info, Node: Numerical Functions, Next: Random Numbers, Prev: Predicates on Numbers, Up: Numbers - -Numerical Functions -=================== - -These functions perform various arithmetic operations on numbers. - - - Function: abs number - This function returns the absolute value of NUMBER. (Newer - versions of Emacs provide this as a built-in function; this package - defines `abs' only for Emacs 18 versions which don't provide it as - a primitive.) - - - Function: expt base power - This function returns BASE raised to the power of NUMBER. (Newer - versions of Emacs provide this as a built-in function; this - package defines `expt' only for Emacs 18 versions which don't - provide it as a primitive.) - - - Function: gcd &rest integers - This function returns the Greatest Common Divisor of the arguments. - For one argument, it returns the absolute value of that argument. - For zero arguments, it returns zero. - - - Function: lcm &rest integers - This function returns the Least Common Multiple of the arguments. - For one argument, it returns the absolute value of that argument. - For zero arguments, it returns one. - - - Function: isqrt integer - This function computes the "integer square root" of its integer - argument, i.e., the greatest integer less than or equal to the true - square root of the argument. - - - Function: floor* number &optional divisor - This function implements the Common Lisp `floor' function. It is - called `floor*' to avoid name conflicts with the simpler `floor' - function built-in to Emacs 19. - - With one argument, `floor*' returns a list of two numbers: The - argument rounded down (toward minus infinity) to an integer, and - the "remainder" which would have to be added back to the first - return value to yield the argument again. If the argument is an - integer X, the result is always the list `(X 0)'. If the argument - is an Emacs 19 floating-point number, the first result is a Lisp - integer and the second is a Lisp float between 0 (inclusive) and 1 - (exclusive). - - With two arguments, `floor*' divides NUMBER by DIVISOR, and - returns the floor of the quotient and the corresponding remainder - as a list of two numbers. If `(floor* X Y)' returns `(Q R)', then - `Q*Y + R = X', with R between 0 (inclusive) and R (exclusive). - Also, note that `(floor* X)' is exactly equivalent to `(floor* X - 1)'. - - This function is entirely compatible with Common Lisp's `floor' - function, except that it returns the two results in a list since - Emacs Lisp does not support multiple-valued functions. - - - Function: ceiling* number &optional divisor - This function implements the Common Lisp `ceiling' function, which - is analogous to `floor' except that it rounds the argument or - quotient of the arguments up toward plus infinity. The remainder - will be between 0 and minus R. - - - Function: truncate* number &optional divisor - This function implements the Common Lisp `truncate' function, - which is analogous to `floor' except that it rounds the argument - or quotient of the arguments toward zero. Thus it is equivalent - to `floor*' if the argument or quotient is positive, or to - `ceiling*' otherwise. The remainder has the same sign as NUMBER. - - - Function: round* number &optional divisor - This function implements the Common Lisp `round' function, which - is analogous to `floor' except that it rounds the argument or - quotient of the arguments to the nearest integer. In the case of - a tie (the argument or quotient is exactly halfway between two - integers), it rounds to the even integer. - - - Function: mod* number divisor - This function returns the same value as the second return value of - `floor'. - - - Function: rem* number divisor - This function returns the same value as the second return value of - `truncate'. - - These definitions are compatible with those in the Quiroz `cl.el' -package, except that this package appends `*' to certain function names -to avoid conflicts with existing Emacs 19 functions, and that the -mechanism for returning multiple values is different. - - -File: cl.info, Node: Random Numbers, Next: Implementation Parameters, Prev: Numerical Functions, Up: Numbers - -Random Numbers -============== - -This package also provides an implementation of the Common Lisp random -number generator. It uses its own additive-congruential algorithm, -which is much more likely to give statistically clean random numbers -than the simple generators supplied by many operating systems. - - - Function: random* number &optional state - This function returns a random nonnegative number less than - NUMBER, and of the same type (either integer or floating-point). - The STATE argument should be a `random-state' object which holds - the state of the random number generator. The function modifies - this state object as a side effect. If STATE is omitted, it - defaults to the variable `*random-state*', which contains a - pre-initialized `random-state' object. - - - Variable: *random-state* - This variable contains the system "default" `random-state' object, - used for calls to `random*' that do not specify an alternative - state object. Since any number of programs in the Emacs process - may be accessing `*random-state*' in interleaved fashion, the - sequence generated from this variable will be irreproducible for - all intents and purposes. - - - Function: make-random-state &optional state - This function creates or copies a `random-state' object. If STATE - is omitted or `nil', it returns a new copy of `*random-state*'. - This is a copy in the sense that future sequences of calls to - `(random* N)' and `(random* N S)' (where S is the new random-state - object) will return identical sequences of random numbers. - - If STATE is a `random-state' object, this function returns a copy - of that object. If STATE is `t', this function returns a new - `random-state' object seeded from the date and time. As an - extension to Common Lisp, STATE may also be an integer in which - case the new object is seeded from that integer; each different - integer seed will result in a completely different sequence of - random numbers. - - It is legal to print a `random-state' object to a buffer or file - and later read it back with `read'. If a program wishes to use a - sequence of pseudo-random numbers which can be reproduced later - for debugging, it can call `(make-random-state t)' to get a new - sequence, then print this sequence to a file. When the program is - later rerun, it can read the original run's random-state from the - file. - - - Function: random-state-p object - This predicate returns `t' if OBJECT is a `random-state' object, - or `nil' otherwise. - diff -u -r -N xemacs-21.4.14/info/cl.info-4 xemacs-21.4.15/info/cl.info-4 --- xemacs-21.4.14/info/cl.info-4 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-4 1969-12-31 19:00:00.000000000 -0500 @@ -1,851 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: Implementation Parameters, Prev: Random Numbers, Up: Numbers - -Implementation Parameters -========================= - -This package defines several useful constants having to with numbers. - - - Variable: most-positive-fixnum - This constant equals the largest value a Lisp integer can hold. - It is typically `2^23-1' or `2^25-1'. - - - Variable: most-negative-fixnum - This constant equals the smallest (most negative) value a Lisp - integer can hold. - - The following parameters have to do with floating-point numbers. -This package determines their values by exercising the computer's -floating-point arithmetic in various ways. Because this operation -might be slow, the code for initializing them is kept in a separate -function that must be called before the parameters can be used. - - - Function: cl-float-limits - This function makes sure that the Common Lisp floating-point - parameters like `most-positive-float' have been initialized. - Until it is called, these parameters will be `nil'. If this - version of Emacs does not support floats (e.g., most versions of - Emacs 18), the parameters will remain `nil'. If the parameters - have already been initialized, the function returns immediately. - - The algorithm makes assumptions that will be valid for most modern - machines, but will fail if the machine's arithmetic is extremely - unusual, e.g., decimal. - - Since true Common Lisp supports up to four different floating-point -precisions, it has families of constants like -`most-positive-single-float', `most-positive-double-float', -`most-positive-long-float', and so on. Emacs has only one -floating-point precision, so this package omits the precision word from -the constants' names. - - - Variable: most-positive-float - This constant equals the largest value a Lisp float can hold. For - those systems whose arithmetic supports infinities, this is the - largest _finite_ value. For IEEE machines, the value is - approximately `1.79e+308'. - - - Variable: most-negative-float - This constant equals the most-negative value a Lisp float can hold. - (It is assumed to be equal to `(- most-positive-float)'.) - - - Variable: least-positive-float - This constant equals the smallest Lisp float value greater than - zero. For IEEE machines, it is about `4.94e-324' if denormals are - supported or `2.22e-308' if not. - - - Variable: least-positive-normalized-float - This constant equals the smallest _normalized_ Lisp float greater - than zero, i.e., the smallest value for which IEEE denormalization - will not result in a loss of precision. For IEEE machines, this - value is about `2.22e-308'. For machines that do not support the - concept of denormalization and gradual underflow, this constant - will always equal `least-positive-float'. - - - Variable: least-negative-float - This constant is the negative counterpart of - `least-positive-float'. - - - Variable: least-negative-normalized-float - This constant is the negative counterpart of - `least-positive-normalized-float'. - - - Variable: float-epsilon - This constant is the smallest positive Lisp float that can be added - to 1.0 to produce a distinct value. Adding a smaller number to 1.0 - will yield 1.0 again due to roundoff. For IEEE machines, epsilon - is about `2.22e-16'. - - - Variable: float-negative-epsilon - This is the smallest positive value that can be subtracted from - 1.0 to produce a distinct value. For IEEE machines, it is about - `1.11e-16'. - - -File: cl.info, Node: Sequences, Next: Lists, Prev: Numbers, Up: Top - -Sequences -********* - -Common Lisp defines a number of functions that operate on "sequences", -which are either lists, strings, or vectors. Emacs Lisp includes a few -of these, notably `elt' and `length'; this package defines most of the -rest. - -* Menu: - -* Sequence Basics:: Arguments shared by all sequence functions -* Mapping over Sequences:: `mapcar*', `mapcan', `map', `every', etc. -* Sequence Functions:: `subseq', `remove*', `substitute', etc. -* Searching Sequences:: `find', `position', `count', `search', etc. -* Sorting Sequences:: `sort*', `stable-sort', `merge' - - -File: cl.info, Node: Sequence Basics, Next: Mapping over Sequences, Prev: Sequences, Up: Sequences - -Sequence Basics -=============== - -Many of the sequence functions take keyword arguments; *note Argument -Lists::. All keyword arguments are optional and, if specified, may -appear in any order. - - The `:key' argument should be passed either `nil', or a function of -one argument. This key function is used as a filter through which the -elements of the sequence are seen; for example, `(find x y :key 'car)' -is similar to `(assoc* x y)': It searches for an element of the list -whose `car' equals `x', rather than for an element which equals `x' -itself. If `:key' is omitted or `nil', the filter is effectively the -identity function. - - The `:test' and `:test-not' arguments should be either `nil', or -functions of two arguments. The test function is used to compare two -sequence elements, or to compare a search value with sequence elements. -(The two values are passed to the test function in the same order as -the original sequence function arguments from which they are derived, -or, if they both come from the same sequence, in the same order as they -appear in that sequence.) The `:test' argument specifies a function -which must return true (non-`nil') to indicate a match; instead, you -may use `:test-not' to give a function which returns _false_ to -indicate a match. The default test function is `:test 'eql'. - - Many functions which take ITEM and `:test' or `:test-not' arguments -also come in `-if' and `-if-not' varieties, where a PREDICATE function -is passed instead of ITEM, and sequence elements match if the predicate -returns true on them (or false in the case of `-if-not'). For example: - - (remove* 0 seq :test '=) == (remove-if 'zerop seq) - -to remove all zeros from sequence `seq'. - - Some operations can work on a subsequence of the argument sequence; -these function take `:start' and `:end' arguments which default to zero -and the length of the sequence, respectively. Only elements between -START (inclusive) and END (exclusive) are affected by the operation. -The END argument may be passed `nil' to signify the length of the -sequence; otherwise, both START and END must be integers, with `0 <= -START <= END <= (length SEQ)'. If the function takes two sequence -arguments, the limits are defined by keywords `:start1' and `:end1' for -the first, and `:start2' and `:end2' for the second. - - A few functions accept a `:from-end' argument, which, if non-`nil', -causes the operation to go from right-to-left through the sequence -instead of left-to-right, and a `:count' argument, which specifies an -integer maximum number of elements to be removed or otherwise processed. - - The sequence functions make no guarantees about the order in which -the `:test', `:test-not', and `:key' functions are called on various -elements. Therefore, it is a bad idea to depend on side effects of -these functions. For example, `:from-end' may cause the sequence to be -scanned actually in reverse, or it may be scanned forwards but -computing a result "as if" it were scanned backwards. (Some functions, -like `mapcar*' and `every', _do_ specify exactly the order in which the -function is called so side effects are perfectly acceptable in those -cases.) - - Strings in GNU Emacs 19 may contain "text properties" as well as -character data. Except as noted, it is undefined whether or not text -properties are preserved by sequence functions. For example, `(remove* -?A STR)' may or may not preserve the properties of the characters -copied from STR into the result. - - -File: cl.info, Node: Mapping over Sequences, Next: Sequence Functions, Prev: Sequence Basics, Up: Sequences - -Mapping over Sequences -====================== - -These functions "map" the function you specify over the elements of -lists or arrays. They are all variations on the theme of the built-in -function `mapcar'. - - - Function: mapcar* function seq &rest more-seqs - This function calls FUNCTION on successive parallel sets of - elements from its argument sequences. Given a single SEQ argument - it is equivalent to `mapcar'; given N sequences, it calls the - function with the first elements of each of the sequences as the N - arguments to yield the first element of the result list, then with - the second elements, and so on. The mapping stops as soon as the - shortest sequence runs out. The argument sequences may be any - mixture of lists, strings, and vectors; the return sequence is - always a list. - - Common Lisp's `mapcar' accepts multiple arguments but works only - on lists; Emacs Lisp's `mapcar' accepts a single sequence - argument. This package's `mapcar*' works as a compatible superset - of both. - - - Function: map result-type function seq &rest more-seqs - This function maps FUNCTION over the argument sequences, just like - `mapcar*', but it returns a sequence of type RESULT-TYPE rather - than a list. RESULT-TYPE must be one of the following symbols: - `vector', `string', `list' (in which case the effect is the same - as for `mapcar*'), or `nil' (in which case the results are thrown - away and `map' returns `nil'). - - - Function: maplist function list &rest more-lists - This function calls FUNCTION on each of its argument lists, then - on the `cdr's of those lists, and so on, until the shortest list - runs out. The results are returned in the form of a list. Thus, - `maplist' is like `mapcar*' except that it passes in the list - pointers themselves rather than the `car's of the advancing - pointers. - - - Function: mapc function seq &rest more-seqs - This function is like `mapcar*', except that the values returned - by FUNCTION are ignored and thrown away rather than being - collected into a list. The return value of `mapc' is SEQ, the - first sequence. - - - Function: mapl function list &rest more-lists - This function is like `maplist', except that it throws away the - values returned by FUNCTION. - - - Function: mapcan function seq &rest more-seqs - This function is like `mapcar*', except that it concatenates the - return values (which must be lists) using `nconc', rather than - simply collecting them into a list. - - - Function: mapcon function list &rest more-lists - This function is like `maplist', except that it concatenates the - return values using `nconc'. - - - Function: some predicate seq &rest more-seqs - This function calls PREDICATE on each element of SEQ in turn; if - PREDICATE returns a non-`nil' value, `some' returns that value, - otherwise it returns `nil'. Given several sequence arguments, it - steps through the sequences in parallel until the shortest one - runs out, just as in `mapcar*'. You can rely on the left-to-right - order in which the elements are visited, and on the fact that - mapping stops immediately as soon as PREDICATE returns non-`nil'. - - - Function: every predicate seq &rest more-seqs - This function calls PREDICATE on each element of the sequence(s) - in turn; it returns `nil' as soon as PREDICATE returns `nil' for - any element, or `t' if the predicate was true for all elements. - - - Function: notany predicate seq &rest more-seqs - This function calls PREDICATE on each element of the sequence(s) - in turn; it returns `nil' as soon as PREDICATE returns a non-`nil' - value for any element, or `t' if the predicate was `nil' for all - elements. - - - Function: notevery predicate seq &rest more-seqs - This function calls PREDICATE on each element of the sequence(s) - in turn; it returns a non-`nil' value as soon as PREDICATE returns - `nil' for any element, or `t' if the predicate was true for all - elements. - - - Function: reduce function seq &key :from-end :start :end - :initial-value :key - This function combines the elements of SEQ using an associative - binary operation. Suppose FUNCTION is `*' and SEQ is the list `(2 - 3 4 5)'. The first two elements of the list are combined with `(* - 2 3) = 6'; this is combined with the next element, `(* 6 4) = 24', - and that is combined with the final element: `(* 24 5) = 120'. - Note that the `*' function happens to be self-reducing, so that - `(* 2 3 4 5)' has the same effect as an explicit call to `reduce'. - - If `:from-end' is true, the reduction is right-associative instead - of left-associative: - - (reduce '- '(1 2 3 4)) - == (- (- (- 1 2) 3) 4) => -8 - (reduce '- '(1 2 3 4) :from-end t) - == (- 1 (- 2 (- 3 4))) => -2 - - If `:key' is specified, it is a function of one argument which is - called on each of the sequence elements in turn. - - If `:initial-value' is specified, it is effectively added to the - front (or rear in the case of `:from-end') of the sequence. The - `:key' function is _not_ applied to the initial value. - - If the sequence, including the initial value, has exactly one - element then that element is returned without ever calling - FUNCTION. If the sequence is empty (and there is no initial - value), then FUNCTION is called with no arguments to obtain the - return value. - - All of these mapping operations can be expressed conveniently in -terms of the `loop' macro. In compiled code, `loop' will be faster -since it generates the loop as in-line code with no function calls. - - -File: cl.info, Node: Sequence Functions, Next: Searching Sequences, Prev: Mapping over Sequences, Up: Sequences - -Sequence Functions -================== - -This section describes a number of Common Lisp functions for operating -on sequences. - - - Function: subseq sequence start &optional end - This function returns a given subsequence of the argument - SEQUENCE, which may be a list, string, or vector. The indices - START and END must be in range, and START must be no greater than - END. If END is omitted, it defaults to the length of the - sequence. The return value is always a copy; it does not share - structure with SEQUENCE. - - As an extension to Common Lisp, START and/or END may be negative, - in which case they represent a distance back from the end of the - sequence. This is for compatibility with Emacs' `substring' - function. Note that `subseq' is the _only_ sequence function that - allows negative START and END. - - You can use `setf' on a `subseq' form to replace a specified range - of elements with elements from another sequence. The replacement - is done as if by `replace', described below. - - - Function: concatenate result-type &rest seqs - This function concatenates the argument sequences together to form - a result sequence of type RESULT-TYPE, one of the symbols - `vector', `string', or `list'. The arguments are always copied, - even in cases such as `(concatenate 'list '(1 2 3))' where the - result is identical to an argument. - - - Function: fill seq item &key :start :end - This function fills the elements of the sequence (or the specified - part of the sequence) with the value ITEM. - - - Function: replace seq1 seq2 &key :start1 :end1 :start2 :end2 - This function copies part of SEQ2 into part of SEQ1. The sequence - SEQ1 is not stretched or resized; the amount of data copied is - simply the shorter of the source and destination (sub)sequences. - The function returns SEQ1. - - If SEQ1 and SEQ2 are `eq', then the replacement will work - correctly even if the regions indicated by the start and end - arguments overlap. However, if SEQ1 and SEQ2 are lists which - share storage but are not `eq', and the start and end arguments - specify overlapping regions, the effect is undefined. - - - Function: remove* item seq &key :test :test-not :key :count :start - :end :from-end - This returns a copy of SEQ with all elements matching ITEM - removed. The result may share storage with or be `eq' to SEQ in - some circumstances, but the original SEQ will not be modified. - The `:test', `:test-not', and `:key' arguments define the matching - test that is used; by default, elements `eql' to ITEM are removed. - The `:count' argument specifies the maximum number of matching - elements that can be removed (only the leftmost COUNT matches are - removed). The `:start' and `:end' arguments specify a region in - SEQ in which elements will be removed; elements outside that - region are not matched or removed. The `:from-end' argument, if - true, says that elements should be deleted from the end of the - sequence rather than the beginning (this matters only if COUNT was - also specified). - - - Function: delete* item seq &key :test :test-not :key :count :start - :end :from-end - This deletes all elements of SEQ which match ITEM. It is a - destructive operation. Since Emacs Lisp does not support - stretchable strings or vectors, this is the same as `remove*' for - those sequence types. On lists, `remove*' will copy the list if - necessary to preserve the original list, whereas `delete*' will - splice out parts of the argument list. Compare `append' and - `nconc', which are analogous non-destructive and destructive list - operations in Emacs Lisp. - - The predicate-oriented functions `remove-if', `remove-if-not', -`delete-if', and `delete-if-not' are defined similarly. - - - Function: delete item list - This MacLisp-compatible function deletes from LIST all elements - which are `equal' to ITEM. The `delete' function is built-in to - Emacs 19; this package defines it equivalently in Emacs 18. - - - Function: remove item list - This function removes from LIST all elements which are `equal' to - ITEM. This package defines it for symmetry with `delete', even - though `remove' is not built-in to Emacs 19. - - - Function: remq item list - This function removes from LIST all elements which are `eq' to - ITEM. This package defines it for symmetry with `delq', even - though `remq' is not built-in to Emacs 19. - - - Function: remove-duplicates seq &key :test :test-not :key :start - :end :from-end - This function returns a copy of SEQ with duplicate elements - removed. Specifically, if two elements from the sequence match - according to the `:test', `:test-not', and `:key' arguments, only - the rightmost one is retained. If `:from-end' is true, the - leftmost one is retained instead. If `:start' or `:end' is - specified, only elements within that subsequence are examined or - removed. - - - Function: delete-duplicates seq &key :test :test-not :key :start - :end :from-end - This function deletes duplicate elements from SEQ. It is a - destructive version of `remove-duplicates'. - - - Function: substitute new old seq &key :test :test-not :key :count - :start :end :from-end - This function returns a copy of SEQ, with all elements matching - OLD replaced with NEW. The `:count', `:start', `:end', and - `:from-end' arguments may be used to limit the number of - substitutions made. - - - Function: nsubstitute new old seq &key :test :test-not :key :count - :start :end :from-end - This is a destructive version of `substitute'; it performs the - substitution using `setcar' or `aset' rather than by returning a - changed copy of the sequence. - - The `substitute-if', `substitute-if-not', `nsubstitute-if', and -`nsubstitute-if-not' functions are defined similarly. For these, a -PREDICATE is given in place of the OLD argument. - - -File: cl.info, Node: Searching Sequences, Next: Sorting Sequences, Prev: Sequence Functions, Up: Sequences - -Searching Sequences -=================== - -These functions search for elements or subsequences in a sequence. -(See also `member*' and `assoc*'; *note Lists::.) - - - Function: find item seq &key :test :test-not :key :start :end - :from-end - This function searches SEQ for an element matching ITEM. If it - finds a match, it returns the matching element. Otherwise, it - returns `nil'. It returns the leftmost match, unless `:from-end' - is true, in which case it returns the rightmost match. The - `:start' and `:end' arguments may be used to limit the range of - elements that are searched. - - - Function: position item seq &key :test :test-not :key :start :end - :from-end - This function is like `find', except that it returns the integer - position in the sequence of the matching item rather than the item - itself. The position is relative to the start of the sequence as - a whole, even if `:start' is non-zero. The function returns `nil' - if no matching element was found. - - - Function: count item seq &key :test :test-not :key :start :end - This function returns the number of elements of SEQ which match - ITEM. The result is always a nonnegative integer. - - The `find-if', `find-if-not', `position-if', `position-if-not', -`count-if', and `count-if-not' functions are defined similarly. - - - Function: mismatch seq1 seq2 &key :test :test-not :key :start1 :end1 - :start2 :end2 :from-end - This function compares the specified parts of SEQ1 and SEQ2. If - they are the same length and the corresponding elements match - (according to `:test', `:test-not', and `:key'), the function - returns `nil'. If there is a mismatch, the function returns the - index (relative to SEQ1) of the first mismatching element. This - will be the leftmost pair of elements which do not match, or the - position at which the shorter of the two otherwise-matching - sequences runs out. - - If `:from-end' is true, then the elements are compared from right - to left starting at `(1- END1)' and `(1- END2)'. If the sequences - differ, then one plus the index of the rightmost difference - (relative to SEQ1) is returned. - - An interesting example is `(mismatch str1 str2 :key 'upcase)', - which compares two strings case-insensitively. - - - Function: search seq1 seq2 &key :test :test-not :key :from-end - :start1 :end1 :start2 :end2 - This function searches SEQ2 for a subsequence that matches SEQ1 - (or part of it specified by `:start1' and `:end1'.) Only matches - which fall entirely within the region defined by `:start2' and - `:end2' will be considered. The return value is the index of the - leftmost element of the leftmost match, relative to the start of - SEQ2, or `nil' if no matches were found. If `:from-end' is true, - the function finds the _rightmost_ matching subsequence. - - -File: cl.info, Node: Sorting Sequences, Prev: Searching Sequences, Up: Sequences - -Sorting Sequences -================= - - - Function: sort* seq predicate &key :key - This function sorts SEQ into increasing order as determined by - using PREDICATE to compare pairs of elements. PREDICATE should - return true (non-`nil') if and only if its first argument is less - than (not equal to) its second argument. For example, `<' and - `string-lessp' are suitable predicate functions for sorting - numbers and strings, respectively; `>' would sort numbers into - decreasing rather than increasing order. - - This function differs from Emacs' built-in `sort' in that it can - operate on any type of sequence, not just lists. Also, it accepts - a `:key' argument which is used to preprocess data fed to the - PREDICATE function. For example, - - (setq data (sort data 'string-lessp :key 'downcase)) - - sorts DATA, a sequence of strings, into increasing alphabetical - order without regard to case. A `:key' function of `car' would be - useful for sorting association lists. - - The `sort*' function is destructive; it sorts lists by actually - rearranging the `cdr' pointers in suitable fashion. - - - Function: stable-sort seq predicate &key :key - This function sorts SEQ "stably", meaning two elements which are - equal in terms of PREDICATE are guaranteed not to be rearranged - out of their original order by the sort. - - In practice, `sort*' and `stable-sort' are equivalent in Emacs - Lisp because the underlying `sort' function is stable by default. - However, this package reserves the right to use non-stable methods - for `sort*' in the future. - - - Function: merge type seq1 seq2 predicate &key :key - This function merges two sequences SEQ1 and SEQ2 by interleaving - their elements. The result sequence, of type TYPE (in the sense - of `concatenate'), has length equal to the sum of the lengths of - the two input sequences. The sequences may be modified - destructively. Order of elements within SEQ1 and SEQ2 is - preserved in the interleaving; elements of the two sequences are - compared by PREDICATE (in the sense of `sort') and the lesser - element goes first in the result. When elements are equal, those - from SEQ1 precede those from SEQ2 in the result. Thus, if SEQ1 - and SEQ2 are both sorted according to PREDICATE, then the result - will be a merged sequence which is (stably) sorted according to - PREDICATE. - - -File: cl.info, Node: Lists, Next: Hash Tables, Prev: Sequences, Up: Top - -Lists -***** - -The functions described here operate on lists. - -* Menu: - -* List Functions:: `caddr', `first', `last', `list*', etc. -* Substitution of Expressions:: `subst', `sublis', etc. -* Lists as Sets:: `member*', `adjoin', `union', etc. -* Association Lists:: `assoc*', `rassoc*', `acons', `pairlis' - - -File: cl.info, Node: List Functions, Next: Substitution of Expressions, Prev: Lists, Up: Lists - -List Functions -============== - -This section describes a number of simple operations on lists, i.e., -chains of cons cells. - - - Function: caddr x - This function is equivalent to `(car (cdr (cdr X)))'. Likewise, - this package defines all 28 `cXXXr' functions where XXX is up to - four `a's and/or `d's. All of these functions are `setf'-able, - and calls to them are expanded inline by the byte-compiler for - maximum efficiency. - - - Function: first x - This function is a synonym for `(car X)'. Likewise, the functions - `second', `third', ..., through `tenth' return the given element - of the list X. - - - Function: rest x - This function is a synonym for `(cdr X)'. - - - Function: endp x - Common Lisp defines this function to act like `null', but - signalling an error if `x' is neither a `nil' nor a cons cell. - This package simply defines `endp' as a synonym for `null'. - - - Function: list-length x - This function returns the length of list X, exactly like `(length - X)', except that if X is a circular list (where the cdr-chain - forms a loop rather than terminating with `nil'), this function - returns `nil'. (The regular `length' function would get stuck if - given a circular list.) - - - Function: last x &optional n - This function returns the last cons, or the Nth-to-last cons, of - the list X. If N is omitted it defaults to 1. The "last cons" - means the first cons cell of the list whose `cdr' is not another - cons cell. (For normal lists, the `cdr' of the last cons will be - `nil'.) This function returns `nil' if X is `nil' or shorter than - N. Note that the last _element_ of the list is `(car (last X))'. - - - Function: butlast x &optional n - This function returns the list X with the last element, or the - last N elements, removed. If N is greater than zero it makes a - copy of the list so as not to damage the original list. In - general, `(append (butlast X N) (last X N))' will return a list - equal to X. - - - Function: nbutlast x &optional n - This is a version of `butlast' that works by destructively - modifying the `cdr' of the appropriate element, rather than making - a copy of the list. - - - Function: list* arg &rest others - This function constructs a list of its arguments. The final - argument becomes the `cdr' of the last cell constructed. Thus, - `(list* A B C)' is equivalent to `(cons A (cons B C))', and - `(list* A B nil)' is equivalent to `(list A B)'. - - (Note that this function really is called `list*' in Common Lisp; - it is not a name invented for this package like `member*' or - `defun*'.) - - - Function: ldiff list sublist - If SUBLIST is a sublist of LIST, i.e., is `eq' to one of the cons - cells of LIST, then this function returns a copy of the part of - LIST up to but not including SUBLIST. For example, `(ldiff x - (cddr x))' returns the first two elements of the list `x'. The - result is a copy; the original LIST is not modified. If SUBLIST - is not a sublist of LIST, a copy of the entire LIST is returned. - - - Function: copy-list list - This function returns a copy of the list LIST. It copies dotted - lists like `(1 2 . 3)' correctly. - - - Function: copy-tree x &optional vecp - This function returns a copy of the tree of cons cells X. Unlike - `copy-sequence' (and its alias `copy-list'), which copies only - along the `cdr' direction, this function copies (recursively) - along both the `car' and the `cdr' directions. If X is not a cons - cell, the function simply returns X unchanged. If the optional - VECP argument is true, this function copies vectors (recursively) - as well as cons cells. - - - Function: tree-equal x y &key :test :test-not :key - This function compares two trees of cons cells. If X and Y are - both cons cells, their `car's and `cdr's are compared recursively. - If neither X nor Y is a cons cell, they are compared by `eql', or - according to the specified test. The `:key' function, if - specified, is applied to the elements of both trees. *Note - Sequences::. - - -File: cl.info, Node: Substitution of Expressions, Next: Lists as Sets, Prev: List Functions, Up: Lists - -Substitution of Expressions -=========================== - -These functions substitute elements throughout a tree of cons cells. -(*Note Sequence Functions::, for the `substitute' function, which works -on just the top-level elements of a list.) - - - Function: subst new old tree &key :test :test-not :key - This function substitutes occurrences of OLD with NEW in TREE, a - tree of cons cells. It returns a substituted tree, which will be - a copy except that it may share storage with the argument TREE in - parts where no substitutions occurred. The original TREE is not - modified. This function recurses on, and compares against OLD, - both `car's and `cdr's of the component cons cells. If OLD is - itself a cons cell, then matching cells in the tree are - substituted as usual without recursively substituting in that - cell. Comparisons with OLD are done according to the specified - test (`eql' by default). The `:key' function is applied to the - elements of the tree but not to OLD. - - - Function: nsubst new old tree &key :test :test-not :key - This function is like `subst', except that it works by destructive - modification (by `setcar' or `setcdr') rather than copying. - - The `subst-if', `subst-if-not', `nsubst-if', and `nsubst-if-not' -functions are defined similarly. - - - Function: sublis alist tree &key :test :test-not :key - This function is like `subst', except that it takes an association - list ALIST of OLD-NEW pairs. Each element of the tree (after - applying the `:key' function, if any), is compared with the `car's - of ALIST; if it matches, it is replaced by the corresponding `cdr'. - - - Function: nsublis alist tree &key :test :test-not :key - This is a destructive version of `sublis'. - - -File: cl.info, Node: Lists as Sets, Next: Association Lists, Prev: Substitution of Expressions, Up: Lists - -Lists as Sets -============= - -These functions perform operations on lists which represent sets of -elements. - - - Function: member item list - This MacLisp-compatible function searches LIST for an element - which is `equal' to ITEM. The `member' function is built-in to - Emacs 19; this package defines it equivalently in Emacs 18. See - the following function for a Common-Lisp compatible version. - - - Function: member* item list &key :test :test-not :key - This function searches LIST for an element matching ITEM. If a - match is found, it returns the cons cell whose `car' was the - matching element. Otherwise, it returns `nil'. Elements are - compared by `eql' by default; you can use the `:test', - `:test-not', and `:key' arguments to modify this behavior. *Note - Sequences::. - - Note that this function's name is suffixed by `*' to avoid the - incompatible `member' function defined in Emacs 19. (That - function uses `equal' for comparisons; it is equivalent to - `(member* ITEM LIST :test 'equal)'.) - - The `member-if' and `member-if-not' functions analogously search for -elements which satisfy a given predicate. - - - Function: tailp sublist list - This function returns `t' if SUBLIST is a sublist of LIST, i.e., - if SUBLIST is `eql' to LIST or to any of its `cdr's. - - - Function: adjoin item list &key :test :test-not :key - This function conses ITEM onto the front of LIST, like `(cons ITEM - LIST)', but only if ITEM is not already present on the list (as - determined by `member*'). If a `:key' argument is specified, it - is applied to ITEM as well as to the elements of LIST during the - search, on the reasoning that ITEM is "about" to become part of - the list. - - - Function: union list1 list2 &key :test :test-not :key - This function combines two lists which represent sets of items, - returning a list that represents the union of those two sets. The - result list will contain all items which appear in LIST1 or LIST2, - and no others. If an item appears in both LIST1 and LIST2 it will - be copied only once. If an item is duplicated in LIST1 or LIST2, - it is undefined whether or not that duplication will survive in the - result list. The order of elements in the result list is also - undefined. - - - Function: nunion list1 list2 &key :test :test-not :key - This is a destructive version of `union'; rather than copying, it - tries to reuse the storage of the argument lists if possible. - - - Function: intersection list1 list2 &key :test :test-not :key - This function computes the intersection of the sets represented by - LIST1 and LIST2. It returns the list of items which appear in - both LIST1 and LIST2. - - - Function: nintersection list1 list2 &key :test :test-not :key - This is a destructive version of `intersection'. It tries to - reuse storage of LIST1 rather than copying. It does _not_ reuse - the storage of LIST2. - - - Function: set-difference list1 list2 &key :test :test-not :key - This function computes the "set difference" of LIST1 and LIST2, - i.e., the set of elements that appear in LIST1 but _not_ in LIST2. - - - Function: nset-difference list1 list2 &key :test :test-not :key - This is a destructive `set-difference', which will try to reuse - LIST1 if possible. - - - Function: set-exclusive-or list1 list2 &key :test :test-not :key - This function computes the "set exclusive or" of LIST1 and LIST2, - i.e., the set of elements that appear in exactly one of LIST1 and - LIST2. - - - Function: nset-exclusive-or list1 list2 &key :test :test-not :key - This is a destructive `set-exclusive-or', which will try to reuse - LIST1 and LIST2 if possible. - - - Function: subsetp list1 list2 &key :test :test-not :key - This function checks whether LIST1 represents a subset of LIST2, - i.e., whether every element of LIST1 also appears in LIST2. - - -File: cl.info, Node: Association Lists, Prev: Lists as Sets, Up: Lists - -Association Lists -================= - -An "association list" is a list representing a mapping from one set of -values to another; any list whose elements are cons cells is an -association list. - - - Function: assoc* item a-list &key :test :test-not :key - This function searches the association list A-LIST for an element - whose `car' matches (in the sense of `:test', `:test-not', and - `:key', or by comparison with `eql') a given ITEM. It returns the - matching element, if any, otherwise `nil'. It ignores elements of - A-LIST which are not cons cells. (This corresponds to the - behavior of `assq' and `assoc' in Emacs Lisp; Common Lisp's - `assoc' ignores `nil's but considers any other non-cons elements - of A-LIST to be an error.) - - - Function: rassoc* item a-list &key :test :test-not :key - This function searches for an element whose `cdr' matches ITEM. - If A-LIST represents a mapping, this applies the inverse of the - mapping to ITEM. - - - Function: rassoc item a-list - This function searches like `rassoc*' with a `:test' argument of - `equal'. It is analogous to Emacs Lisp's standard `assoc' - function, which derives from the MacLisp rather than the Common - Lisp tradition. - - The `assoc-if', `assoc-if-not', `rassoc-if', and `rassoc-if-not' -functions are defined similarly. - - Two simple functions for constructing association lists are: - - - Function: acons key value alist - This is equivalent to `(cons (cons KEY VALUE) ALIST)'. - - - Function: pairlis keys values &optional alist - This is equivalent to `(nconc (mapcar* 'cons KEYS VALUES) ALIST)'. - - -File: cl.info, Node: Hash Tables, Next: Structures, Prev: Lists, Up: Top - -Hash Tables -*********** - -Hash tables are now implemented directly in the C code and documented in -*Note Hash Tables: (lispref)Hash Tables. - diff -u -r -N xemacs-21.4.14/info/cl.info-5 xemacs-21.4.15/info/cl.info-5 --- xemacs-21.4.14/info/cl.info-5 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-5 1969-12-31 19:00:00.000000000 -0500 @@ -1,913 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: Structures, Next: Assertions, Prev: Hash Tables, Up: Top - -Structures -********** - -The Common Lisp "structure" mechanism provides a general way to define -data types similar to C's `struct' types. A structure is a Lisp object -containing some number of "slots", each of which can hold any Lisp data -object. Functions are provided for accessing and setting the slots, -creating or copying structure objects, and recognizing objects of a -particular structure type. - - In true Common Lisp, each structure type is a new type distinct from -all existing Lisp types. Since the underlying Emacs Lisp system -provides no way to create new distinct types, this package implements -structures as vectors (or lists upon request) with a special "tag" -symbol to identify them. - - - Special Form: defstruct name slots... - The `defstruct' form defines a new structure type called NAME, - with the specified SLOTS. (The SLOTS may begin with a string - which documents the structure type.) In the simplest case, NAME - and each of the SLOTS are symbols. For example, - - (defstruct person name age sex) - - defines a struct type called `person' which contains three slots. - Given a `person' object P, you can access those slots by calling - `(person-name P)', `(person-age P)', and `(person-sex P)'. You - can also change these slots by using `setf' on any of these place - forms: - - (incf (person-age birthday-boy)) - - You can create a new `person' by calling `make-person', which - takes keyword arguments `:name', `:age', and `:sex' to specify the - initial values of these slots in the new object. (Omitting any of - these arguments leaves the corresponding slot "undefined," - according to the Common Lisp standard; in Emacs Lisp, such - uninitialized slots are filled with `nil'.) - - Given a `person', `(copy-person P)' makes a new object of the same - type whose slots are `eq' to those of P. - - Given any Lisp object X, `(person-p X)' returns true if X looks - like a `person', false otherwise. (Again, in Common Lisp this - predicate would be exact; in Emacs Lisp the best it can do is - verify that X is a vector of the correct length which starts with - the correct tag symbol.) - - Accessors like `person-name' normally check their arguments - (effectively using `person-p') and signal an error if the argument - is the wrong type. This check is affected by `(optimize (safety - ...))' declarations. Safety level 1, the default, uses a somewhat - optimized check that will detect all incorrect arguments, but may - use an uninformative error message (e.g., "expected a vector" - instead of "expected a `person'"). Safety level 0 omits all - checks except as provided by the underlying `aref' call; safety - levels 2 and 3 do rigorous checking that will always print a - descriptive error message for incorrect inputs. *Note - Declarations::. - - (setq dave (make-person :name "Dave" :sex 'male)) - => [cl-struct-person "Dave" nil male] - (setq other (copy-person dave)) - => [cl-struct-person "Dave" nil male] - (eq dave other) - => nil - (eq (person-name dave) (person-name other)) - => t - (person-p dave) - => t - (person-p [1 2 3 4]) - => nil - (person-p "Bogus") - => nil - (person-p '[cl-struct-person counterfeit person object]) - => t - - In general, NAME is either a name symbol or a list of a name - symbol followed by any number of "struct options"; each SLOT is - either a slot symbol or a list of the form `(SLOT-NAME - DEFAULT-VALUE SLOT-OPTIONS...)'. The DEFAULT-VALUE is a Lisp form - which is evaluated any time an instance of the structure type is - created without specifying that slot's value. - - Common Lisp defines several slot options, but the only one - implemented in this package is `:read-only'. A non-`nil' value - for this option means the slot should not be `setf'-able; the - slot's value is determined when the object is created and does not - change afterward. - - (defstruct person - (name nil :read-only t) - age - (sex 'unknown)) - - Any slot options other than `:read-only' are ignored. - - For obscure historical reasons, structure options take a different - form than slot options. A structure option is either a keyword - symbol, or a list beginning with a keyword symbol possibly followed - by arguments. (By contrast, slot options are key-value pairs not - enclosed in lists.) - - (defstruct (person (:constructor create-person) - (:type list) - :named) - name age sex) - - The following structure options are recognized. - - `:conc-name' - The argument is a symbol whose print name is used as the - prefix for the names of slot accessor functions. The default - is the name of the struct type followed by a hyphen. The - option `(:conc-name p-)' would change this prefix to `p-'. - Specifying `nil' as an argument means no prefix, so that the - slot names themselves are used to name the accessor functions. - - `:constructor' - In the simple case, this option takes one argument which is an - alternate name to use for the constructor function. The - default is `make-NAME', e.g., `make-person'. The above - example changes this to `create-person'. Specifying `nil' as - an argument means that no standard constructor should be - generated at all. - - In the full form of this option, the constructor name is - followed by an arbitrary argument list. *Note Program - Structure::, for a description of the format of Common Lisp - argument lists. All options, such as `&rest' and `&key', are - supported. The argument names should match the slot names; - each slot is initialized from the corresponding argument. - Slots whose names do not appear in the argument list are - initialized based on the DEFAULT-VALUE in their slot - descriptor. Also, `&optional' and `&key' arguments which - don't specify defaults take their defaults from the slot - descriptor. It is legal to include arguments which don't - correspond to slot names; these are useful if they are - referred to in the defaults for optional, keyword, or `&aux' - arguments which _do_ correspond to slots. - - You can specify any number of full-format `:constructor' - options on a structure. The default constructor is still - generated as well unless you disable it with a simple-format - `:constructor' option. - - (defstruct - (person - (:constructor nil) ; no default constructor - (:constructor new-person (name sex &optional (age 0))) - (:constructor new-hound (&key (name "Rover") - (dog-years 0) - &aux (age (* 7 dog-years)) - (sex 'canine)))) - name age sex) - - The first constructor here takes its arguments positionally - rather than by keyword. (In official Common Lisp - terminology, constructors that work By Order of Arguments - instead of by keyword are called "BOA constructors." No, I'm - not making this up.) For example, `(new-person "Jane" - 'female)' generates a person whose slots are `"Jane"', 0, and - `female', respectively. - - The second constructor takes two keyword arguments, `:name', - which initializes the `name' slot and defaults to `"Rover"', - and `:dog-years', which does not itself correspond to a slot - but which is used to initialize the `age' slot. The `sex' - slot is forced to the symbol `canine' with no syntax for - overriding it. - - `:copier' - The argument is an alternate name for the copier function for - this type. The default is `copy-NAME'. `nil' means not to - generate a copier function. (In this implementation, all - copier functions are simply synonyms for `copy-sequence'.) - - `:predicate' - The argument is an alternate name for the predicate which - recognizes objects of this type. The default is `NAME-p'. - `nil' means not to generate a predicate function. (If the - `:type' option is used without the `:named' option, no - predicate is ever generated.) - - In true Common Lisp, `typep' is always able to recognize a - structure object even if `:predicate' was used. In this - package, `typep' simply looks for a function called - `TYPENAME-p', so it will work for structure types only if - they used the default predicate name. - - `:include' - This option implements a very limited form of C++-style - inheritance. The argument is the name of another structure - type previously created with `defstruct'. The effect is to - cause the new structure type to inherit all of the included - structure's slots (plus, of course, any new slots described - by this struct's slot descriptors). The new structure is - considered a "specialization" of the included one. In fact, - the predicate and slot accessors for the included type will - also accept objects of the new type. - - If there are extra arguments to the `:include' option after - the included-structure name, these options are treated as - replacement slot descriptors for slots in the included - structure, possibly with modified default values. Borrowing - an example from Steele: - - (defstruct person name (age 0) sex) - => person - (defstruct (astronaut (:include person (age 45))) - helmet-size - (favorite-beverage 'tang)) - => astronaut - - (setq joe (make-person :name "Joe")) - => [cl-struct-person "Joe" 0 nil] - (setq buzz (make-astronaut :name "Buzz")) - => [cl-struct-astronaut "Buzz" 45 nil nil tang] - - (list (person-p joe) (person-p buzz)) - => (t t) - (list (astronaut-p joe) (astronaut-p buzz)) - => (nil t) - - (person-name buzz) - => "Buzz" - (astronaut-name joe) - => error: "astronaut-name accessing a non-astronaut" - - Thus, if `astronaut' is a specialization of `person', then - every `astronaut' is also a `person' (but not the other way - around). Every `astronaut' includes all the slots of a - `person', plus extra slots that are specific to astronauts. - Operations that work on people (like `person-name') work on - astronauts just like other people. - - `:print-function' - In full Common Lisp, this option allows you to specify a - function which is called to print an instance of the - structure type. The Emacs Lisp system offers no hooks into - the Lisp printer which would allow for such a feature, so - this package simply ignores `:print-function'. - - `:type' - The argument should be one of the symbols `vector' or `list'. - This tells which underlying Lisp data type should be used to - implement the new structure type. Vectors are used by - default, but `(:type list)' will cause structure objects to - be stored as lists instead. - - The vector representation for structure objects has the - advantage that all structure slots can be accessed quickly, - although creating vectors is a bit slower in Emacs Lisp. - Lists are easier to create, but take a relatively long time - accessing the later slots. - - `:named' - This option, which takes no arguments, causes a - characteristic "tag" symbol to be stored at the front of the - structure object. Using `:type' without also using `:named' - will result in a structure type stored as plain vectors or - lists with no identifying features. - - The default, if you don't specify `:type' explicitly, is to - use named vectors. Therefore, `:named' is only useful in - conjunction with `:type'. - - (defstruct (person1) name age sex) - (defstruct (person2 (:type list) :named) name age sex) - (defstruct (person3 (:type list)) name age sex) - - (setq p1 (make-person1)) - => [cl-struct-person1 nil nil nil] - (setq p2 (make-person2)) - => (person2 nil nil nil) - (setq p3 (make-person3)) - => (nil nil nil) - - (person1-p p1) - => t - (person2-p p2) - => t - (person3-p p3) - => error: function person3-p undefined - - Since unnamed structures don't have tags, `defstruct' is not - able to make a useful predicate for recognizing them. Also, - accessors like `person3-name' will be generated but they will - not be able to do any type checking. The `person3-name' - function, for example, will simply be a synonym for `car' in - this case. By contrast, `person2-name' is able to verify - that its argument is indeed a `person2' object before - proceeding. - - `:initial-offset' - The argument must be a nonnegative integer. It specifies a - number of slots to be left "empty" at the front of the - structure. If the structure is named, the tag appears at the - specified position in the list or vector; otherwise, the first - slot appears at that position. Earlier positions are filled - with `nil' by the constructors and ignored otherwise. If the - type `:include's another type, then `:initial-offset' - specifies a number of slots to be skipped between the last - slot of the included type and the first new slot. - - Except as noted, the `defstruct' facility of this package is -entirely compatible with that of Common Lisp. - - -File: cl.info, Node: Assertions, Next: Efficiency Concerns, Prev: Structures, Up: Top - -Assertions and Errors -********************* - -This section describes two macros that test "assertions", i.e., -conditions which must be true if the program is operating correctly. -Assertions never add to the behavior of a Lisp program; they simply -make "sanity checks" to make sure everything is as it should be. - - If the optimization property `speed' has been set to 3, and `safety' -is less than 3, then the byte-compiler will optimize away the following -assertions. Because assertions might be optimized away, it is a bad -idea for them to include side-effects. - - - Special Form: assert test-form [show-args string args...] - This form verifies that TEST-FORM is true (i.e., evaluates to a - non-`nil' value). If so, it returns `nil'. If the test is not - satisfied, `assert' signals an error. - - A default error message will be supplied which includes TEST-FORM. - You can specify a different error message by including a STRING - argument plus optional extra arguments. Those arguments are simply - passed to `error' to signal the error. - - If the optional second argument SHOW-ARGS is `t' instead of `nil', - then the error message (with or without STRING) will also include - all non-constant arguments of the top-level FORM. For example: - - (assert (> x 10) t "x is too small: %d") - - This usage of SHOW-ARGS is a change to Common Lisp. In true - Common Lisp, the second argument gives a list of PLACES which can - be `setf''d by the user before continuing from the error. - - - Special Form: check-type place type &optional string - This form verifies that PLACE evaluates to a value of type TYPE. - If so, it returns `nil'. If not, `check-type' signals a - continuable `wrong-type-argument' error. The default error - message lists the erroneous value along with TYPE and PLACE - themselves. If STRING is specified, it is included in the error - message in place of TYPE. For example: - - (check-type x (integer 1 *) "a positive integer") - - *Note Type Predicates::, for a description of the type specifiers - that may be used for TYPE. - - Note that as in Common Lisp, the first argument to `check-type' - should be a PLACE suitable for use by `setf', because `check-type' - signals a continuable error that allows the user to modify PLACE, - most simply by returning a value from the debugger. - - The following error-related macro is also defined: - - - Special Form: ignore-errors forms... - This executes FORMS exactly like a `progn', except that errors are - ignored during the FORMS. More precisely, if an error is - signalled then `ignore-errors' immediately aborts execution of the - FORMS and returns `nil'. If the FORMS complete successfully, - `ignore-errors' returns the result of the last FORM. - - -File: cl.info, Node: Efficiency Concerns, Next: Common Lisp Compatibility, Prev: Assertions, Up: Top - -Efficiency Concerns -******************* - -Macros -====== - -Many of the advanced features of this package, such as `defun*', -`loop', and `setf', are implemented as Lisp macros. In byte-compiled -code, these complex notations will be expanded into equivalent Lisp -code which is simple and efficient. For example, the forms - - (incf i n) - (push x (car p)) - -are expanded at compile-time to the Lisp forms - - (setq i (+ i n)) - (setcar p (cons x (car p))) - -which are the most efficient ways of doing these respective operations -in Lisp. Thus, there is no performance penalty for using the more -readable `incf' and `push' forms in your compiled code. - - _Interpreted_ code, on the other hand, must expand these macros -every time they are executed. For this reason it is strongly -recommended that code making heavy use of macros be compiled. (The -features labelled "Special Form" instead of "Function" in this manual -are macros.) A loop using `incf' a hundred times will execute -considerably faster if compiled, and will also garbage-collect less -because the macro expansion will not have to be generated, used, and -thrown away a hundred times. - - You can find out how a macro expands by using the `cl-prettyexpand' -function. - - - Function: cl-prettyexpand form &optional full - This function takes a single Lisp form as an argument and inserts - a nicely formatted copy of it in the current buffer (which must be - in Lisp mode so that indentation works properly). It also expands - all Lisp macros which appear in the form. The easiest way to use - this function is to go to the `*scratch*' buffer and type, say, - - (cl-prettyexpand '(loop for x below 10 collect x)) - - and type `C-x C-e' immediately after the closing parenthesis; the - expansion - - (block nil - (let* ((x 0) - (G1004 nil)) - (while (< x 10) - (setq G1004 (cons x G1004)) - (setq x (+ x 1))) - (nreverse G1004))) - - will be inserted into the buffer. (The `block' macro is expanded - differently in the interpreter and compiler, so `cl-prettyexpand' - just leaves it alone. The temporary variable `G1004' was created - by `gensym'.) - - If the optional argument FULL is true, then _all_ macros are - expanded, including `block', `eval-when', and compiler macros. - Expansion is done as if FORM were a top-level form in a file being - compiled. For example, - - (cl-prettyexpand '(pushnew 'x list)) - -| (setq list (adjoin 'x list)) - (cl-prettyexpand '(pushnew 'x list) t) - -| (setq list (if (memq 'x list) list (cons 'x list))) - (cl-prettyexpand '(caddr (member* 'a list)) t) - -| (car (cdr (cdr (memq 'a list)))) - - Note that `adjoin', `caddr', and `member*' all have built-in - compiler macros to optimize them in common cases. - - -Error Checking -============== - -Common Lisp compliance has in general not been sacrificed for the sake -of efficiency. A few exceptions have been made for cases where -substantial gains were possible at the expense of marginal -incompatibility. One example is the use of `memq' (which is treated -very efficiently by the byte-compiler) to scan for keyword arguments; -this can become confused in rare cases when keyword symbols are used as -both keywords and data values at once. This is extremely unlikely to -occur in practical code, and the use of `memq' allows functions with -keyword arguments to be nearly as fast as functions that use -`&optional' arguments. - - The Common Lisp standard (as embodied in Steele's book) uses the -phrase "it is an error if" to indicate a situation which is not -supposed to arise in complying programs; implementations are strongly -encouraged but not required to signal an error in these situations. -This package sometimes omits such error checking in the interest of -compactness and efficiency. For example, `do' variable specifiers are -supposed to be lists of one, two, or three forms; extra forms are -ignored by this package rather than signalling a syntax error. The -`endp' function is simply a synonym for `null' in this package. -Functions taking keyword arguments will accept an odd number of -arguments, treating the trailing keyword as if it were followed by the -value `nil'. - - Argument lists (as processed by `defun*' and friends) _are_ checked -rigorously except for the minor point just mentioned; in particular, -keyword arguments are checked for validity, and `&allow-other-keys' and -`:allow-other-keys' are fully implemented. Keyword validity checking -is slightly time consuming (though not too bad in byte-compiled code); -you can use `&allow-other-keys' to omit this check. Functions defined -in this package such as `find' and `member*' do check their keyword -arguments for validity. - - -Optimizing Compiler -=================== - -The byte-compiler that comes with Emacs 18 normally fails to expand -macros that appear in top-level positions in the file (i.e., outside of -`defun's or other enclosing forms). This would have disastrous -consequences to programs that used such top-level macros as `defun*', -`eval-when', and `defstruct'. To work around this problem, the "CL" -package patches the Emacs 18 compiler to expand top-level macros. This -patch will apply to your own macros, too, if they are used in a -top-level context. The patch will not harm versions of the Emacs 18 -compiler which have already had a similar patch applied, nor will it -affect the optimizing Emacs 19 byte-compiler written by Jamie Zawinski -and Hallvard Furuseth. The patch is applied to the byte compiler's -code in Emacs' memory, _not_ to the `bytecomp.elc' file stored on disk. - - The Emacs 19 compiler (for Emacs 18) is available from various Emacs -Lisp archive sites such as `archive.cis.ohio-state.edu'. Its use is -highly recommended; many of the Common Lisp macros emit code which can -be improved by optimization. In particular, `block's (whether explicit -or implicit in constructs like `defun*' and `loop') carry a fair -run-time penalty; the optimizing compiler removes `block's which are -not actually referenced by `return' or `return-from' inside the block. - - -File: cl.info, Node: Common Lisp Compatibility, Next: Old CL Compatibility, Prev: Efficiency Concerns, Up: Top - -Common Lisp Compatibility -************************* - -Following is a list of all known incompatibilities between this package -and Common Lisp as documented in Steele (2nd edition). - - Certain function names, such as `member', `assoc', and `floor', were -already taken by (incompatible) Emacs Lisp functions; this package -appends `*' to the names of its Common Lisp versions of these functions. - - The word `defun*' is required instead of `defun' in order to use -extended Common Lisp argument lists in a function. Likewise, -`defmacro*' and `function*' are versions of those forms which -understand full-featured argument lists. The `&whole' keyword does not -work in `defmacro' argument lists (except inside recursive argument -lists). - - In order to allow an efficient implementation, keyword arguments use -a slightly cheesy parser which may be confused if a keyword symbol is -passed as the _value_ of another keyword argument. (Specifically, -`(memq :KEYWORD REST-OF-ARGUMENTS)' is used to scan for `:KEYWORD' -among the supplied keyword arguments.) - - The `eql' and `equal' predicates do not distinguish between IEEE -floating-point plus and minus zero. The `equalp' predicate has several -differences with Common Lisp; *note Predicates::. - - The `setf' mechanism is entirely compatible, except that -setf-methods return a list of five values rather than five values -directly. Also, the new "`setf' function" concept (typified by `(defun -(setf foo) ...)') is not implemented. - - The `do-all-symbols' form is the same as `do-symbols' with no -OBARRAY argument. In Common Lisp, this form would iterate over all -symbols in all packages. Since Emacs obarrays are not a first-class -package mechanism, there is no way for `do-all-symbols' to locate any -but the default obarray. - - The `loop' macro is complete except that `loop-finish' and type -specifiers are unimplemented. - - The multiple-value return facility treats lists as multiple values, -since Emacs Lisp cannot support multiple return values directly. The -macros will be compatible with Common Lisp if `values' or `values-list' -is always used to return to a `multiple-value-bind' or other -multiple-value receiver; if `values' is used without -`multiple-value-...' or vice-versa the effect will be different from -Common Lisp. - - Many Common Lisp declarations are ignored, and others match the -Common Lisp standard in concept but not in detail. For example, local -`special' declarations, which are purely advisory in Emacs Lisp, do not -rigorously obey the scoping rules set down in Steele's book. - - The variable `*gensym-counter*' starts out with a pseudo-random -value rather than with zero. This is to cope with the fact that -generated symbols become interned when they are written to and loaded -back from a file. - - The `defstruct' facility is compatible, except that structures are -of type `:type vector :named' by default rather than some special, -distinct type. Also, the `:type' slot option is ignored. - - The second argument of `check-type' is treated differently. - - -File: cl.info, Node: Old CL Compatibility, Next: Porting Common Lisp, Prev: Common Lisp Compatibility, Up: Top - -Old CL Compatibility -******************** - -Following is a list of all known incompatibilities between this package -and the older Quiroz `cl.el' package. - - This package's emulation of multiple return values in functions is -incompatible with that of the older package. That package attempted to -come as close as possible to true Common Lisp multiple return values; -unfortunately, it could not be 100% reliable and so was prone to -occasional surprises if used freely. This package uses a simpler -method, namely replacing multiple values with lists of values, which is -more predictable though more noticeably different from Common Lisp. - - The `defkeyword' form and `keywordp' function are not implemented in -this package. - - The `member', `floor', `ceiling', `truncate', `round', `mod', and -`rem' functions are suffixed by `*' in this package to avoid collision -with existing functions in Emacs 18 or Emacs 19. The older package -simply redefined these functions, overwriting the built-in meanings and -causing serious portability problems with Emacs 19. (Some more recent -versions of the Quiroz package changed the names to `cl-member', etc.; -this package defines the latter names as aliases for `member*', etc.) - - Certain functions in the old package which were buggy or inconsistent -with the Common Lisp standard are incompatible with the conforming -versions in this package. For example, `eql' and `member' were -synonyms for `eq' and `memq' in that package, `setf' failed to preserve -correct order of evaluation of its arguments, etc. - - Finally, unlike the older package, this package is careful to prefix -all of its internal names with `cl-'. Except for a few functions which -are explicitly defined as additional features (such as `floatp-safe' -and `letf'), this package does not export any non-`cl-' symbols which -are not also part of Common Lisp. - - -The `cl-compat' package -======================= - -The "CL" package includes emulations of some features of the old -`cl.el', in the form of a compatibility package `cl-compat'. To use -it, put `(require 'cl-compat)' in your program. - - The old package defined a number of internal routines without `cl-' -prefixes or other annotations. Call to these routines may have crept -into existing Lisp code. `cl-compat' provides emulations of the -following internal routines: `pair-with-newsyms', `zip-lists', -`unzip-lists', `reassemble-arglists', `duplicate-symbols-p', -`safe-idiv'. - - Some `setf' forms translated into calls to internal functions that -user code might call directly. The functions `setnth', `setnthcdr', -and `setelt' fall in this category; they are defined by `cl-compat', -but the best fix is to change to use `setf' properly. - - The `cl-compat' file defines the keyword functions `keywordp', -`keyword-of', and `defkeyword', which are not defined by the new "CL" -package because the use of keywords as data is discouraged. - - The `build-klist' mechanism for parsing keyword arguments is -emulated by `cl-compat'; the `with-keyword-args' macro is not, however, -and in any case it's best to change to use the more natural keyword -argument processing offered by `defun*'. - - Multiple return values are treated differently by the two Common -Lisp packages. The old package's method was more compatible with true -Common Lisp, though it used heuristics that caused it to report -spurious multiple return values in certain cases. The `cl-compat' -package defines a set of multiple-value macros that are compatible with -the old CL package; again, they are heuristic in nature, but they are -guaranteed to work in any case where the old package's macros worked. -To avoid name collision with the "official" multiple-value facilities, -the ones in `cl-compat' have capitalized names: `Values', -`Values-list', `Multiple-value-bind', etc. - - The functions `cl-floor', `cl-ceiling', `cl-truncate', and -`cl-round' are defined by `cl-compat' to use the old-style -multiple-value mechanism, just as they did in the old package. The -newer `floor*' and friends return their two results in a list rather -than as multiple values. Note that older versions of the old package -used the unadorned names `floor', `ceiling', etc.; `cl-compat' cannot -use these names because they conflict with Emacs 19 built-ins. - - -File: cl.info, Node: Porting Common Lisp, Next: Function Index, Prev: Old CL Compatibility, Up: Top - -Porting Common Lisp -******************* - -This package is meant to be used as an extension to Emacs Lisp, not as -an Emacs implementation of true Common Lisp. Some of the remaining -differences between Emacs Lisp and Common Lisp make it difficult to -port large Common Lisp applications to Emacs. For one, some of the -features in this package are not fully compliant with ANSI or Steele; -*note Common Lisp Compatibility::. But there are also quite a few -features that this package does not provide at all. Here are some -major omissions that you will want watch out for when bringing Common -Lisp code into Emacs. - - * Case-insensitivity. Symbols in Common Lisp are case-insensitive - by default. Some programs refer to a function or variable as - `foo' in one place and `Foo' or `FOO' in another. Emacs Lisp will - treat these as three distinct symbols. - - Some Common Lisp code is written in all upper-case. While Emacs - is happy to let the program's own functions and variables use this - convention, calls to Lisp builtins like `if' and `defun' will have - to be changed to lower-case. - - * Lexical scoping. In Common Lisp, function arguments and `let' - bindings apply only to references physically within their bodies - (or within macro expansions in their bodies). Emacs Lisp, by - contrast, uses "dynamic scoping" wherein a binding to a variable - is visible even inside functions called from the body. - - Variables in Common Lisp can be made dynamically scoped by - declaring them `special' or using `defvar'. In Emacs Lisp it is - as if all variables were declared `special'. - - Often you can use code that was written for lexical scoping even - in a dynamically scoped Lisp, but not always. Here is an example - of a Common Lisp code fragment that would fail in Emacs Lisp: - - (defun map-odd-elements (func list) - (loop for x in list - for flag = t then (not flag) - collect (if flag x (funcall func x)))) - - (defun add-odd-elements (list x) - (map-odd-elements (function (lambda (a) (+ a x))) list)) - - In Common Lisp, the two functions' usages of `x' are completely - independent. In Emacs Lisp, the binding to `x' made by - `add-odd-elements' will have been hidden by the binding in - `map-odd-elements' by the time the `(+ a x)' function is called. - - (This package avoids such problems in its own mapping functions by - using names like `cl-x' instead of `x' internally; as long as you - don't use the `cl-' prefix for your own variables no collision can - occur.) - - *Note Lexical Bindings::, for a description of the `lexical-let' - form which establishes a Common Lisp-style lexical binding, and - some examples of how it differs from Emacs' regular `let'. - - * Common Lisp allows the shorthand `#'x' to stand for `(function - x)', just as `'x' stands for `(quote x)'. In Common Lisp, one - traditionally uses `#'' notation when referring to the name of a - function. In Emacs Lisp, it works just as well to use a regular - quote: - - (loop for x in y by #'cddr collect (mapcar #'plusp x)) ; Common Lisp - (loop for x in y by 'cddr collect (mapcar 'plusp x)) ; Emacs Lisp - - When `#'' introduces a `lambda' form, it is best to write out - `(function ...)' longhand in Emacs Lisp. You can use a regular - quote, but then the byte-compiler won't know that the `lambda' - expression is code that can be compiled. - - (mapcar #'(lambda (x) (* x 2)) list) ; Common Lisp - (mapcar (function (lambda (x) (* x 2))) list) ; Emacs Lisp - - XEmacs supports `#'' notation starting with version 19.8. - - * Reader macros. Common Lisp includes a second type of macro that - works at the level of individual characters. For example, Common - Lisp implements the quote notation by a reader macro called `'', - whereas Emacs Lisp's parser just treats quote as a special case. - Some Lisp packages use reader macros to create special syntaxes - for themselves, which the Emacs parser is incapable of reading. - - * Other syntactic features. Common Lisp provides a number of - notations beginning with `#' that the Emacs Lisp parser won't - understand. For example, `#| ... |#' is an alternate comment - notation, and `#+lucid (foo)' tells the parser to ignore the - `(foo)' except in Lucid Common Lisp. - - The number prefixes `#b', `#o', and `#x', however, are supported - by the Emacs Lisp parser to represent numbers in binary, octal, - and hexadecimal notation (or radix), just like in Common Lisp. - - * Packages. In Common Lisp, symbols are divided into "packages". - Symbols that are Lisp built-ins are typically stored in one - package; symbols that are vendor extensions are put in another, - and each application program would have a package for its own - symbols. Certain symbols are "exported" by a package and others - are internal; certain packages "use" or import the exported symbols - of other packages. To access symbols that would not normally be - visible due to this importing and exporting, Common Lisp provides - a syntax like `package:symbol' or `package::symbol'. - - Emacs Lisp has a single namespace for all interned symbols, and - then uses a naming convention of putting a prefix like `cl-' in - front of the name. Some Emacs packages adopt the Common Lisp-like - convention of using `cl:' or `cl::' as the prefix. However, the - Emacs parser does not understand colons and just treats them as - part of the symbol name. Thus, while `mapcar' and `lisp:mapcar' - may refer to the same symbol in Common Lisp, they are totally - distinct in Emacs Lisp. Common Lisp programs which refer to a - symbol by the full name sometimes and the short name other times - will not port cleanly to Emacs. - - Emacs Lisp does have a concept of "obarrays," which are - package-like collections of symbols, but this feature is not - strong enough to be used as a true package mechanism. - - * Keywords. The notation `:test-not' in Common Lisp really is a - shorthand for `keyword:test-not'; keywords are just symbols in a - built-in `keyword' package with the special property that all its - symbols are automatically self-evaluating. Common Lisp programs - often use keywords liberally to avoid having to use quotes. - - In Emacs Lisp a keyword is just a symbol whose name begins with a - colon; since the Emacs parser does not treat them specially, they - have to be explicitly made self-evaluating by a statement like - `(setq :test-not ':test-not)'. This package arranges to execute - such a statement whenever `defun*' or some other form sees a - keyword being used as an argument. Common Lisp code that assumes - that a symbol `:mumble' will be self-evaluating even though it was - never introduced by a `defun*' will have to be fixed. - - * The `format' function is quite different between Common Lisp and - Emacs Lisp. It takes an additional "destination" argument before - the format string. A destination of `nil' means to format to a - string as in Emacs Lisp; a destination of `t' means to write to - the terminal (similar to `message' in Emacs). Also, format - control strings are utterly different; `~' is used instead of `%' - to introduce format codes, and the set of available codes is much - richer. There are no notations like `\n' for string literals; - instead, `format' is used with the "newline" format code, `~%'. - More advanced formatting codes provide such features as paragraph - filling, case conversion, and even loops and conditionals. - - While it would have been possible to implement most of Common Lisp - `format' in this package (under the name `format*', of course), it - was not deemed worthwhile. It would have required a huge amount - of code to implement even a decent subset of `format*', yet the - functionality it would provide over Emacs Lisp's `format' would - rarely be useful. - - * Vector constants use square brackets in Emacs Lisp, but `#(a b c)' - notation in Common Lisp. To further complicate matters, Emacs 19 - introduces its own `#(' notation for something entirely - different--strings with properties. - - * Characters are distinct from integers in Common Lisp. The - notation for character constants is also different: `#\A' instead - of `?A'. Also, `string=' and `string-equal' are synonyms in Emacs - Lisp whereas the latter is case-insensitive in Common Lisp. - - * Data types. Some Common Lisp data types do not exist in Emacs - Lisp. Rational numbers and complex numbers are not present, nor - are large integers (all integers are "fixnums"). All arrays are - one-dimensional. There are no readtables or pathnames; streams - are a set of existing data types rather than a new data type of - their own. Hash tables, random-states, structures, and packages - (obarrays) are built from Lisp vectors or lists rather than being - distinct types. - - * The Common Lisp Object System (CLOS) is not implemented, nor is - the Common Lisp Condition System. - - * Common Lisp features that are completely redundant with Emacs Lisp - features of a different name generally have not been implemented. - For example, Common Lisp writes `defconstant' where Emacs Lisp - uses `defconst'. Similarly, `make-list' takes its arguments in - different ways in the two Lisps but does exactly the same thing, - so this package has not bothered to implement a Common Lisp-style - `make-list'. - - * A few more notable Common Lisp features not included in this - package: `compiler-let', `tagbody', `prog', `ldb/dpb', - `parse-integer', `cerror'. - - * Recursion. While recursion works in Emacs Lisp just like it does - in Common Lisp, various details of the Emacs Lisp system and - compiler make recursion much less efficient than it is in most - Lisps. Some schools of thought prefer to use recursion in Lisp - over other techniques; they would sum a list of numbers using - something like - - (defun sum-list (list) - (if list - (+ (car list) (sum-list (cdr list))) - 0)) - - where a more iteratively-minded programmer might write one of - these forms: - - (let ((total 0)) (dolist (x my-list) (incf total x)) total) - (loop for x in my-list sum x) - - While this would be mainly a stylistic choice in most Common Lisps, - in Emacs Lisp you should be aware that the iterative forms are - much faster than recursion. Also, Lisp programmers will want to - note that the current Emacs Lisp compiler does not optimize tail - recursion. - diff -u -r -N xemacs-21.4.14/info/cl.info-6 xemacs-21.4.15/info/cl.info-6 --- xemacs-21.4.14/info/cl.info-6 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/cl.info-6 1969-12-31 19:00:00.000000000 -0500 @@ -1,245 +0,0 @@ -This is ../info/cl.info, produced by makeinfo version 4.5 from cl.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Common Lisp: (cl). GNU Emacs Common Lisp emulation package. -END-INFO-DIR-ENTRY - - This file documents the GNU Emacs Common Lisp emulation package. - - Copyright (C) 1993 Free Software Foundation, Inc. - - 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 author instead of in -the original English. - - -File: cl.info, Node: Function Index, Next: Variable Index, Prev: Porting Common Lisp, Up: Top - -Function Index -************** - -* Menu: - -* abs: Numerical Functions. -* acons: Association Lists. -* adjoin: Lists as Sets. -* assert: Assertions. -* assoc*: Association Lists. -* assoc-if: Association Lists. -* assoc-if-not: Association Lists. -* block: Blocks and Exits. -* butlast: List Functions. -* caddr: List Functions. -* callf: Modify Macros. -* callf2: Modify Macros. -* case: Conditionals. -* ceiling*: Numerical Functions. -* check-type: Assertions. -* cl-float-limits: Implementation Parameters. -* cl-prettyexpand: Efficiency Concerns. -* coerce: Type Predicates. -* compiler-macroexpand: Macros. -* concatenate: Sequence Functions. -* copy-list: List Functions. -* copy-tree: List Functions. -* count: Searching Sequences. -* count-if: Searching Sequences. -* count-if-not: Searching Sequences. -* decf: Modify Macros. -* declaim: Declarations. -* declare: Declarations. -* defalias: Function Aliases. -* define-compiler-macro: Macros. -* define-modify-macro: Customizing Setf. -* define-setf-method: Customizing Setf. -* defmacro*: Argument Lists. -* defsetf: Customizing Setf. -* defstruct: Structures. -* defsubst*: Argument Lists. -* deftype: Type Predicates. -* defun*: Argument Lists. -* delete: Sequence Functions. -* delete*: Sequence Functions. -* delete-duplicates: Sequence Functions. -* delete-if: Sequence Functions. -* delete-if-not: Sequence Functions. -* destructuring-bind: Macros. -* do: Iteration. -* do*: Iteration. -* do-all-symbols: Iteration. -* do-symbols: Iteration. -* dolist: Iteration. -* dotimes: Iteration. -* ecase: Conditionals. -* endp: List Functions. -* eql: Equality Predicates. -* equalp: Equality Predicates. -* etypecase: Conditionals. -* eval-when: Time of Evaluation. -* eval-when-compile: Time of Evaluation. -* evenp: Predicates on Numbers. -* every: Mapping over Sequences. -* expt: Numerical Functions. -* fill: Sequence Functions. -* find: Searching Sequences. -* find-if: Searching Sequences. -* find-if-not: Searching Sequences. -* first: List Functions. -* flet: Function Bindings. -* floatp-safe: Predicates on Numbers. -* floor*: Numerical Functions. -* function*: Argument Lists. -* gcd: Numerical Functions. -* gensym: Creating Symbols. -* gentemp: Creating Symbols. -* get-setf-method: Customizing Setf. -* getf: Property Lists. -* ignore-errors: Assertions. -* incf: Modify Macros. -* intersection: Lists as Sets. -* isqrt: Numerical Functions. -* labels: Function Bindings. -* last: List Functions. -* lcm: Numerical Functions. -* ldiff: List Functions. -* letf: Modify Macros. -* letf*: Modify Macros. -* lexical-let: Lexical Bindings. -* lexical-let*: Lexical Bindings. -* list*: List Functions. -* list-length: List Functions. -* load-time-value: Time of Evaluation. -* locally: Declarations. -* loop <1>: Loop Basics. -* loop: Iteration. -* macrolet: Macro Bindings. -* make-random-state: Random Numbers. -* map: Mapping over Sequences. -* mapc: Mapping over Sequences. -* mapcan: Mapping over Sequences. -* mapcar*: Mapping over Sequences. -* mapcon: Mapping over Sequences. -* mapl: Mapping over Sequences. -* maplist: Mapping over Sequences. -* member: Lists as Sets. -* member*: Lists as Sets. -* member-if: Lists as Sets. -* member-if-not: Lists as Sets. -* merge: Sorting Sequences. -* minusp: Predicates on Numbers. -* mismatch: Searching Sequences. -* mod*: Numerical Functions. -* multiple-value-bind: Multiple Values. -* multiple-value-setq: Multiple Values. -* nbutlast: List Functions. -* nintersection: Lists as Sets. -* notany: Mapping over Sequences. -* notevery: Mapping over Sequences. -* nset-difference: Lists as Sets. -* nset-exclusive-or: Lists as Sets. -* nsublis: Substitution of Expressions. -* nsubst: Substitution of Expressions. -* nsubst-if: Substitution of Expressions. -* nsubst-if-not: Substitution of Expressions. -* nsubstitute: Sequence Functions. -* nsubstitute-if: Sequence Functions. -* nsubstitute-if-not: Sequence Functions. -* nunion: Lists as Sets. -* oddp: Predicates on Numbers. -* pairlis: Association Lists. -* plusp: Predicates on Numbers. -* pop: Modify Macros. -* position: Searching Sequences. -* position-if: Searching Sequences. -* position-if-not: Searching Sequences. -* proclaim: Declarations. -* progv: Dynamic Bindings. -* psetf: Modify Macros. -* psetq: Assignment. -* push: Modify Macros. -* pushnew: Modify Macros. -* random*: Random Numbers. -* random-state-p: Random Numbers. -* rassoc: Association Lists. -* rassoc*: Association Lists. -* rassoc-if: Association Lists. -* rassoc-if-not: Association Lists. -* reduce: Mapping over Sequences. -* rem*: Numerical Functions. -* remf: Property Lists. -* remove: Sequence Functions. -* remove*: Sequence Functions. -* remove-duplicates: Sequence Functions. -* remove-if: Sequence Functions. -* remove-if-not: Sequence Functions. -* remq: Sequence Functions. -* replace: Sequence Functions. -* rest: List Functions. -* return: Blocks and Exits. -* return-from: Blocks and Exits. -* rotatef: Modify Macros. -* round*: Numerical Functions. -* search: Searching Sequences. -* set-difference: Lists as Sets. -* set-exclusive-or: Lists as Sets. -* setf: Basic Setf. -* shiftf: Modify Macros. -* some: Mapping over Sequences. -* sort*: Sorting Sequences. -* stable-sort: Sorting Sequences. -* sublis: Substitution of Expressions. -* subseq: Sequence Functions. -* subsetp: Lists as Sets. -* subst: Substitution of Expressions. -* subst-if: Substitution of Expressions. -* subst-if-not: Substitution of Expressions. -* substitute: Sequence Functions. -* substitute-if: Sequence Functions. -* substitute-if-not: Sequence Functions. -* symbol-macrolet: Macro Bindings. -* tailp: Lists as Sets. -* the: Declarations. -* tree-equal: List Functions. -* truncate*: Numerical Functions. -* typecase: Conditionals. -* typep: Type Predicates. -* union: Lists as Sets. -* unless: Conditionals. -* when: Conditionals. - - -File: cl.info, Node: Variable Index, Prev: Function Index, Up: Top - -Variable Index -************** - -* Menu: - -* *gensym-counter*: Creating Symbols. -* *random-state*: Random Numbers. -* float-epsilon: Implementation Parameters. -* float-negative-epsilon: Implementation Parameters. -* least-negative-float: Implementation Parameters. -* least-negative-normalized-float: Implementation Parameters. -* least-positive-float: Implementation Parameters. -* least-positive-normalized-float: Implementation Parameters. -* most-negative-fixnum: Implementation Parameters. -* most-negative-float: Implementation Parameters. -* most-positive-fixnum: Implementation Parameters. -* most-positive-float: Implementation Parameters. - - diff -u -r -N xemacs-21.4.14/info/custom.info xemacs-21.4.15/info/custom.info --- xemacs-21.4.14/info/custom.info 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/custom.info 2004-02-02 22:01:03.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/custom.info, produced by makeinfo version 4.5 from +This is ../info/custom.info, produced by makeinfo version 4.6 from custom.texi. INFO-DIR-SECTION XEmacs Editor @@ -12,7 +12,7 @@ The Customization Library ************************* - This manual describes how to declare customization groups, variables, +This manual describes how to declare customization groups, variables, and faces. It doesn't contain any examples, but please look at the file `cus-edit.el' which contains many declarations you can learn from. @@ -56,7 +56,7 @@ Declaring Groups ================ - Use `defgroup' to declare new customization groups. +Use `defgroup' to declare new customization groups. - Function: defgroup symbol members doc [keyword value]... Declare SYMBOL as a customization group containing MEMBERS. @@ -87,7 +87,7 @@ Declaring Variables =================== - Use `defcustom' to declare user editable variables. +Use `defcustom' to declare user editable variables. - Function: defcustom symbol value doc [keyword value]... Declare SYMBOL as a customizable variable that defaults to VALUE. @@ -169,7 +169,7 @@ Declaring Faces =============== - Faces are declared with `defface'. +Faces are declared with `defface'. - Function: defface face spec doc [keyword value]... Declare FACE as a customizable face that defaults to SPEC. FACE @@ -218,11 +218,11 @@ Usage for Package Authors ========================= - The recommended usage for the author of a typical emacs lisp package -is to create one group identifying the package, and make all user -options and faces members of that group. If the package has more than -around 20 such options, they should be divided into a number of -subgroups, with each subgroup being member of the top level group. +The recommended usage for the author of a typical emacs lisp package is +to create one group identifying the package, and make all user options +and faces members of that group. If the package has more than around 20 +such options, they should be divided into a number of subgroups, with +each subgroup being member of the top level group. The top level group for the package should itself be member of one or more of the standard customization groups. There exists a group for @@ -235,7 +235,7 @@ Utilities ========= - These utilities can come in handy when adding customization support. +These utilities can come in handy when adding customization support. - Widget: custom-manual Widget type for specifying the info manual entry for a @@ -264,7 +264,7 @@ The Init File ============= - Customizations are saved to the file specified by `custom-file', as +Customizations are saved to the file specified by `custom-file', as calls to `custom-set-variables' and `custom-set-faces'. When you save customizations, the current implementation removes the @@ -277,7 +277,7 @@ XEmacs 21.4 and later). If you use another file, you must explicitly load it yourself. - As of XEmacs 21.4.7, when CUSTOM-FILE is present, it is loaded + As of XEmacs 21.4.7, when `custom-file' is present, it is loaded _after_ `init.el'. This is likely to change in the future, because (1) actions in `init.el' often would like to depend on customizations for consistent appearance and (2) Custom is quite brutal about enforcing @@ -396,12 +396,12 @@  Tag Table: Node: Top204 -Node: Declaring Groups1625 -Node: Declaring Variables2726 -Node: Declaring Faces5818 -Node: Usage for Package Authors7516 -Node: Utilities8295 -Node: The Init File9379 -Node: Wishlist10407 +Node: Declaring Groups1622 +Node: Declaring Variables2720 +Node: Declaring Faces5809 +Node: Usage for Package Authors7504 +Node: Utilities8280 +Node: The Init File9361 +Node: Wishlist10388  End Tag Table diff -u -r -N xemacs-21.4.14/info/emodules.info xemacs-21.4.15/info/emodules.info --- xemacs-21.4.14/info/emodules.info 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/emodules.info 2004-02-02 22:01:03.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/emodules.info, produced by makeinfo version 4.5 from +This is ../info/emodules.info, produced by makeinfo version 4.6 from emodules.texi. This file documents the module loading technology of XEmacs. @@ -75,7 +75,7 @@ Introduction ************ - XEmacs is a powerful, extensible editor. The traditional way of +XEmacs is a powerful, extensible editor. The traditional way of extending the functionality of XEmacs 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 XEmacs in more @@ -159,8 +159,8 @@ Anatomy of a Module ******************* - Each dynamically loadable XEmacs extension (hereafter referred to as -a module) has a certain compulsory format, and must contain several +Each dynamically loadable XEmacs extension (hereafter referred 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 @@ -179,14 +179,14 @@ Required Header File ==================== - Every module must include the file `'. This will -include several other XEmacs internal header files, and will set up -certain vital macros. One of the most important files included by -`emodules.h' is the generated `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 `config.h'. Please read that file to familiarize -yourself with the macros defined there. +Every module must include the file `'. This will include +several other XEmacs internal header files, and will set up certain +vital macros. One of the most important files included by `emodules.h' +is the generated `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 +`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 XEmacs internal header @@ -228,7 +228,7 @@ Required Functions ================== - Every module requires several initialization functions. It is the +Every module requires several initialization functions. It is the responsibility of these functions to load in any dependent modules, and to declare all variables and functions which are to be made visible to the XEmacs Lisp reader. Each of these functions performs a very @@ -280,7 +280,7 @@ Required Variables ================== - Not only does a module need to declare the initialization functions +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 _not_ required to provide these variables in your @@ -334,12 +334,11 @@ Loading other Modules ===================== - During the loading of a module, it is the responsibility of the -function `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 dependencies, it must call -`emodules_load': +During the loading of a module, it is the responsibility of the function +`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 dependencies, it must call `emodules_load': int emodules_load (const char *module, const char *modname, @@ -391,9 +390,9 @@ Using `ellcc' ************* - 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 XEmacs. There is little difference between +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 XEmacs. 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. @@ -429,10 +428,10 @@ Compile Mode ============ - By default, `ellcc' is in "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 `--mode=compile' argument to +By default, `ellcc' is in "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 `--mode=compile' argument to `ellcc'. In this mode, `ellcc' is simply a front-end to the same C compiler @@ -463,7 +462,7 @@ Initialization Mode =================== - XEmacs uses a rather bizarre way of documenting variables and +XEmacs 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 @@ -571,7 +570,7 @@ Link Mode ========= - Once all of your source code files have been compiled (including the +Once all of your source code files have been compiled (including the generated init file) you need to link them all together to create the loadable module. To do this, you invoke `ellcc' in link mode, by passing the `--mode=link' option. You need to specify the final output @@ -595,7 +594,7 @@ Other `ellcc' options ===================== - Aside from the three main `ellcc' modes described above, `ellcc' can +Aside from the three main `ellcc' modes described above, `ellcc' can accept several other options. These are typically used in a `Makefile' to determine installation paths. `ellcc' also allows you to over-ride several of its built-in compiler and linker options using environment @@ -663,11 +662,11 @@ Environment Variables ===================== - During its normal operation, `ellcc' uses the compiler and linker -flags that were determined at the time XEmacs 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 `ellcc' +During its normal operation, `ellcc' uses the compiler and linker flags +that were determined at the time XEmacs 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 `ellcc' recognizes. `ELLCC' @@ -710,8 +709,8 @@ Defining Functions ****************** - One of the main reasons you would ever write a module is to provide -one or more "functions" for the user or the editor to use. The term +One of the main reasons you would ever write a module is to provide one +or more "functions" for the user or the editor to use. The term "function" is a bit overloaded here, as it refers to both a C function and the way it appears to Lisp, which is a "subroutine", or simply a "subr". A Lisp subr is also known as a Lisp primitive, but that term @@ -750,8 +749,8 @@ Using `DEFUN' ============= - Although the full syntax of a function declaration is discussed in -the XEmacs internals manual in greater depth, what follows is a brief +Although the full syntax of a function declaration is discussed in the +XEmacs 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 `DEFUN' macro. Here is a small example: @@ -793,7 +792,7 @@ Declaring Functions =================== - Simply writing the code for a function is not enough to make it +Simply writing the code for a function is not enough to make it available to the Lisp reader. You have to, during module initialization, let the Lisp reader know about the new function. This is done by calling `DEFSUBR' with the name of the function. This is @@ -824,7 +823,7 @@ Defining Variables ****************** - Rarely will you write a module that only contains functions. It is +Rarely will you write a module that only contains functions. It is common to also provide variables which can be used to control the behavior of the function, or store the results of the function being executed. The actual C variable types are the same for modules and @@ -953,21 +952,21 @@ Tag Table: Node: Top1536 Node: Introduction2883 -Node: Anatomy of a Module7391 -Node: Required Header File8205 -Node: Required Functions10124 -Node: Required Variables12848 -Node: Loading other Modules15534 -Node: Using ellcc18451 -Node: Compile Mode20245 -Node: Initialization Mode21613 -Node: Link Mode26643 -Node: Other ellcc options27788 -Node: Environment Variables30367 -Node: Defining Functions32058 -Node: Using DEFUN34069 -Node: Declaring Functions35780 -Node: Defining Variables37123 -Node: Index39366 +Node: Anatomy of a Module7388 +Node: Required Header File8199 +Node: Required Functions10115 +Node: Required Variables12836 +Node: Loading other Modules15519 +Node: Using ellcc18432 +Node: Compile Mode20223 +Node: Initialization Mode21588 +Node: Link Mode26615 +Node: Other ellcc options27757 +Node: Environment Variables30333 +Node: Defining Functions32022 +Node: Using DEFUN34030 +Node: Declaring Functions35738 +Node: Defining Variables37078 +Node: Index39318  End Tag Table diff -u -r -N xemacs-21.4.14/info/external-widget.info xemacs-21.4.15/info/external-widget.info --- xemacs-21.4.14/info/external-widget.info 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/external-widget.info 2004-02-02 22:01:03.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/external-widget.info, produced by makeinfo version 4.5 +This is ../info/external-widget.info, produced by makeinfo version 4.6 from external-widget.texi. INFO-DIR-SECTION XEmacs Editor @@ -26,10 +26,10 @@ Using an External Client Widget ******************************* - There are three different implementations of the external client -widget. One is designed for use in Motif applications and is linked -with the option `-lextcli_Xm'. Another is designed for non-Motif -applications that still use the X toolkit; it is linked with the option +There are three different implementations of the external client widget. +One is designed for use in Motif applications and is linked with the +option `-lextcli_Xm'. Another is designed for non-Motif applications +that still use the X toolkit; it is linked with the option `-lextcli_Xt'. The third is designed for applications that do not use the X toolkit; it is linked with the option `-lextcli_Xlib'. In order to use an external client widget in a client program that uses the X @@ -60,9 +60,9 @@ External Client Widget Resource Settings **************************************** - The external client widget is a subclass of the Motif widget -XmPrimitive and thus inherits all its resources. In addition, the -following new resources are defined: +The external client widget is a subclass of the Motif widget XmPrimitive +and thus inherits all its resources. In addition, the following new +resources are defined: `deadShell (class DeadShell)' A boolean resource indicating whether the last request to the @@ -116,7 +116,7 @@ Motif-Specific Info About the External Client Widget **************************************************** - By default, the external client widget has navigation type +By default, the external client widget has navigation type `XmTAB_GROUP'. The widget traversal keystrokes are modified slightly from the @@ -133,7 +133,7 @@ External Client Widget Internals ******************************** - The following text is lifted verbatim from Ben Wing's comments in +The following text is lifted verbatim from Ben Wing's comments in `ExternalShell.c'. This is a special Shell that is designed to use an externally- @@ -240,8 +240,8 @@ Tag Table: Node: Top232 Node: Using an External Client Widget699 -Node: External Client Widget Resource Settings2414 -Node: Motif-Specific Info About the External Client Widget5157 -Node: External Client Widget Internals5971 +Node: External Client Widget Resource Settings2410 +Node: Motif-Specific Info About the External Client Widget5150 +Node: External Client Widget Internals5961  End Tag Table diff -u -r -N xemacs-21.4.14/info/info.info xemacs-21.4.15/info/info.info --- xemacs-21.4.14/info/info.info 2003-09-03 22:39:01.000000000 -0400 +++ xemacs-21.4.15/info/info.info 2004-02-02 22:01:03.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/info.info, produced by makeinfo version 4.5 from +This is ../info/info.info, produced by makeinfo version 4.6 from info.texi. INFO-DIR-SECTION Texinfo documentation system @@ -31,7 +31,7 @@ Info: An Introduction ********************* - Info is a program for reading documentation, which you might be using +Info is a program for reading documentation, which you might be using now to read this. To learn how to use Info, type the command `h' while using the Info @@ -49,7 +49,7 @@ Getting Started *************** - This first part of the Info manual describes how to get around inside +This first part of the Info manual describes how to get around inside of Info. The second part of the manual describes various advanced Info commands, and how to write an Info as distinct from a Texinfo file. The third part is about how to generate Info files from Texinfo files. @@ -70,7 +70,7 @@ Starting Info on a Small Screen =============================== - Since your terminal has an unusually small number of lines on its +Since your terminal has an unusually small number of lines on its screen, it is necessary to give you special advice at the beginning. If you see the text `--All----' at near the bottom right corner of @@ -134,7 +134,7 @@ How to use Info =============== - You are talking to the program Info, for reading documentation. +You are talking to the program Info, for reading documentation. Right now you are looking at one "Node" of Information. A node contains text describing a specific topic at a specific level of @@ -161,7 +161,7 @@ Returning to the Previous node ============================== - This node is called `Help-P'. The `Previous' node, as you see, is +This node is called `Help-P'. The `Previous' node, as you see, is `Help', which is the one you just came from using the `n' command. Another `n' command now would take you to the next node, `Help-^L'. @@ -182,7 +182,7 @@ The Space, Delete, B and ^L commands. ===================================== - This node's header tells you that you are now at node `Help-^L', and +This node's header tells you that you are now at node `Help-^L', and that `p' would get you back to `Help-P'. The node's title is underlined; it says what the node is about (most nodes have titles). @@ -246,7 +246,7 @@ Menus ===== - Menus and the `m' command +Menus and the `m' command With only the `n' and `p' commands for moving between nodes, nodes are restricted to a linear sequence. Menus allow a branching @@ -382,12 +382,12 @@ The `u' command --------------- - Congratulations! This is the node `Help-FOO'. Unlike the other -nodes you have seen, this one has an `Up': `Help-M', the node you just -came from via the `m' command. This is the usual convention--the nodes -you reach from a menu have `Up' nodes that lead back to the menu. -Menus move Down in the tree, and `Up' moves Up. `Previous', on the -other hand, is usually used to "stay on the same level but go backwards" +Congratulations! This is the node `Help-FOO'. Unlike the other nodes +you have seen, this one has an `Up': `Help-M', the node you just came +from via the `m' command. This is the usual convention--the nodes you +reach from a menu have `Up' nodes that lead back to the menu. Menus +move Down in the tree, and `Up' moves Up. `Previous', on the other +hand, is usually used to "stay on the same level but go backwards" You can go back to the node `Help-M' by typing the command `u' for "Up". That puts you at the _front_ of the node--to get back to where @@ -401,7 +401,7 @@ Some advanced Info commands =========================== - The course is almost over, so please stick with it to the end. +The course is almost over, so please stick with it to the end. If you have been moving around to different nodes and wish to retrace your steps, the `l' command (`l' for "last") will do that, one @@ -465,7 +465,7 @@ The node reached by the cross reference in Info ----------------------------------------------- - This is the node reached by the cross reference named `Cross'. +This is the node reached by the cross reference named `Cross'. While this node is specifically intended to be reached by a cross reference, most cross references lead to nodes that "belong" someplace @@ -482,7 +482,7 @@ Quitting Info ============= - To get out of Info, back to what you were doing before, type `q' for +To get out of Info, back to what you were doing before, type `q' for "Quit". This is the end of the course on using Info. There are some other @@ -501,9 +501,9 @@ Info for Experts **************** - This chapter describes various advanced Info commands, and how to -write an Info as distinct from a Texinfo file. (However, in most -cases, writing a Texinfo file is better, since you can use it _both_ to +This chapter describes various advanced Info commands, and how to write +an Info as distinct from a Texinfo file. (However, in most cases, +writing a Texinfo file is better, since you can use it _both_ to generate an Info file and to make a printed manual. *Note Overview of Texinfo: (texinfo)Top.) @@ -524,7 +524,7 @@ Advanced Info Commands ====================== - `g', `s', `1', - `9', and `e' +`g', `s', `1', - `9', and `e' If you know a node's name, you can go there by typing `g', the name, and . Thus, `gTop' would go to the node called `Top' in this @@ -579,7 +579,7 @@ Adding a new node to Info ========================= - To add a new topic to the list in the Info directory, you must: +To add a new topic to the list in the Info directory, you must: 1. Create some nodes, in some file, to document that topic. 2. Put that topic in the menu in the directory. *Note Menu: Menus. @@ -646,7 +646,7 @@ How to Create Menus =================== - Any node in the Info hierarchy may have a "menu"--a list of subnodes. +Any node in the Info hierarchy may have a "menu"--a list of subnodes. The `m' command searches the current node's menu for the topic which it reads from the terminal. @@ -701,7 +701,7 @@ Creating Cross References ========================= - A cross reference can be placed anywhere in the text, unlike a menu +A cross reference can be placed anywhere in the text, unlike a menu item which must go at the front of a line. A cross reference looks like a menu item except that it has `*note' instead of `*'. It _cannot_ be terminated by a `)', because `)''s are so often part of @@ -720,9 +720,9 @@ Tag Tables for Info Files ========================= - You can speed up the access to nodes of a large Info file by giving -it a tag table. Unlike the tag table for a program, the tag table for -an Info file lives inside the file itself and is used automatically +You can speed up the access to nodes of a large Info file by giving it +a tag table. Unlike the tag table for a program, the tag table for an +Info file lives inside the file itself and is used automatically whenever Info reads in the file. To make a tag table, go to a node in the file using Emacs Info mode @@ -756,10 +756,10 @@ Checking an Info File ===================== - When creating an Info file, it is easy to forget the name of a node -when you are making a pointer to it from another node. If you put in -the wrong name for a node, this is not detected until someone tries to -go through the pointer using Info. Verification of the Info file is an +When creating an Info file, it is easy to forget the name of a node when +you are making a pointer to it from another node. If you put in the +wrong name for a node, this is not detected until someone tries to go +through the pointer using Info. Verification of the Info file is an automatic process which checks all pointers to nodes and reports any pointers which are invalid. Every `Next', `Previous', and `Up' is checked, as is every menu item and every cross reference. In addition, @@ -776,10 +776,10 @@ Emacs Info-mode Variables ========================= - The following variables may modify the behavior of Info-mode in -Emacs; you may wish to set one or several of these variables -interactively, or in your `~/.emacs' init file. *Note Examining and -Setting Variables: (xemacs)Examining. +The following variables may modify the behavior of Info-mode in Emacs; +you may wish to set one or several of these variables interactively, or +in your `~/.emacs' init file. *Note Examining and Setting Variables: +(xemacs)Examining. `Info-enable-edit' Set to `nil', disables the `e' (`Info-edit') command. A non-`nil' @@ -804,7 +804,7 @@ Creating an Info File ********************* - *Note Overview of Texinfo: (texinfo)Top, to learn how to write a +*Note Overview of Texinfo: (texinfo)Top, to learn how to write a Texinfo file. *Note Creating an Info File: (texinfo)Create an Info File, to learn @@ -817,24 +817,24 @@  Tag Table: Node: Top1067 -Node: Getting Started1612 -Node: Help-Small-Screen2360 -Node: Help4109 -Node: Help-P5139 -Node: Help-^L6001 -Node: Help-M8879 -Node: Help-FOO14859 -Node: Help-Adv15597 -Node: Help-Cross18272 -Node: Help-Q18918 -Node: Advanced Info19545 -Node: Expert20523 -Node: Add23037 -Node: Menus26397 -Node: Cross-refs29271 -Node: Tags29973 -Node: Checking31275 -Node: Emacs Info Variables32228 -Node: Creating an Info File33217 +Node: Getting Started1609 +Node: Help-Small-Screen2354 +Node: Help4100 +Node: Help-P5127 +Node: Help-^L5986 +Node: Help-M8861 +Node: Help-FOO14838 +Node: Help-Adv15574 +Node: Help-Cross18246 +Node: Help-Q18889 +Node: Advanced Info19513 +Node: Expert20488 +Node: Add22999 +Node: Menus26356 +Node: Cross-refs29227 +Node: Tags29926 +Node: Checking31225 +Node: Emacs Info Variables32175 +Node: Creating an Info File33161  End Tag Table diff -u -r -N xemacs-21.4.14/info/internals.info xemacs-21.4.15/info/internals.info --- xemacs-21.4.14/info/internals.info 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info 2004-02-02 22:01:07.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from +This is ../info/internals.info, produced by makeinfo version 4.6 from internals/internals.texi. INFO-DIR-SECTION XEmacs Editor @@ -7,8 +7,9 @@ END-INFO-DIR-ENTRY Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. +Microsystems. Copyright (C) 1994 - 1998, 2002, 2003 Free Software +Foundation. Copyright (C) 1994, 1995 Board of Trustees, University of +Illinois. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -39,163 +40,157 @@  Indirect: -internals.info-1: 1776 -internals.info-2: 51668 -internals.info-3: 99044 -internals.info-4: 144735 -internals.info-5: 191272 -internals.info-6: 237550 -internals.info-7: 283860 -internals.info-8: 333298 -internals.info-9: 382330 +internals.info-1: 1789 +internals.info-2: 301402  Tag Table: (Indirect) -Node: Top1776 -Node: A History of Emacs7144 -Node: Through Version 188669 -Node: Lucid Emacs12090 -Node: GNU Emacs 1916134 +Node: Top1789 +Node: A History of Emacs7157 +Node: Through Version 188679 +Node: Lucid Emacs12097 +Node: GNU Emacs 1916138 Node: GNU Emacs 2018317 -Node: XEmacs18744 -Node: XEmacs From the Outside25856 -Node: The Lisp Language27623 -Node: XEmacs From the Perspective of Building37166 -Node: XEmacs From the Inside43291 -Node: The XEmacs Object System (Abstractly Speaking)51668 -Node: How Lisp Objects Are Represented in C65754 -Node: Rules When Writing New C Code71843 -Node: General Coding Rules72692 -Node: Writing Lisp Primitives78464 -Node: Writing Good Comments89627 -Node: Adding Global Lisp Variables93166 -Node: Proper Use of Unsigned Types96815 -Node: Coding for Mule98065 -Node: Character-Related Data Types99044 -Node: Working With Character and Byte Positions102017 -Node: Conversion to and from External Data105782 -Node: General Guidelines for Writing Mule-Aware Code111923 -Node: An Example of Mule-Aware Code114611 -Node: Techniques for XEmacs Developers116592 -Node: Regression Testing XEmacs125428 -Node: A Summary of the Various XEmacs Modules129877 -Node: Low-Level Modules130728 -Node: Basic Lisp Modules138141 -Node: Modules for Standard Editing Operations144735 -Node: Editor-Level Control Flow Modules150623 -Node: Modules for the Basic Displayable Lisp Objects154134 -Node: Modules for other Display-Related Lisp Objects157087 -Node: Modules for the Redisplay Mechanism158762 -Node: Modules for Interfacing with the File System161134 -Node: Modules for Other Aspects of the Lisp Interpreter and Object System164832 -Node: Modules for Interfacing with the Operating System171539 -Node: Modules for Interfacing with X Windows179095 -Node: Modules for Internationalization182578 -Node: Modules for Regression Testing185254 -Node: Allocation of Objects in XEmacs Lisp185954 -Node: Introduction to Allocation186475 -Node: Garbage Collection190116 -Node: GCPROing191272 -Node: Garbage Collection - Step by Step198432 -Node: Invocation198824 -Node: garbage_collect_1201795 -Node: mark_object211277 -Node: gc_sweep213089 -Node: sweep_lcrecords_1218152 -Node: compact_string_chars219147 -Node: sweep_strings221327 -Node: sweep_bit_vectors_1222292 -Node: Integers and Characters222968 -Node: Allocation from Frob Blocks223720 -Node: lrecords225324 -Node: Low-level allocation237550 -Node: Cons241657 -Node: Vector242383 -Node: Bit Vector242960 -Node: Symbol243453 -Node: Marker243807 -Node: String244362 -Node: Compiled Function247975 -Node: Dumping248144 -Node: Overview250365 -Node: Data descriptions250919 -Node: Dumping phase252924 -Node: Object inventory253327 -Node: Address allocation256241 -Node: The header257630 -Node: Data dumping258075 -Node: Pointers dumping258736 -Node: Reloading phase260126 -Node: Remaining issues261680 -Node: Events and the Event Loop262641 -Node: Introduction to Events263091 -Node: Main Loop265006 -Node: Specifics of the Event Gathering Mechanism268581 -Node: Specifics About the Emacs Event281034 -Node: The Event Stream Callback Routines281289 -Node: Other Event Loop Functions281534 -Node: Converting Events282674 -Node: Dispatching Events; The Command Builder283283 -Node: Evaluation; Stack Frames; Bindings283518 -Node: Evaluation283860 -Node: Dynamic Binding; The specbinding Stack; Unwind-Protects290372 -Node: Simple Special Forms292756 -Node: Catch and Throw293539 -Node: Symbols and Variables296114 -Node: Introduction to Symbols296378 -Node: Obarrays297416 -Node: Symbol Values300949 -Node: Buffers and Textual Representation303237 -Node: Introduction to Buffers303895 -Node: The Text in a Buffer306558 -Node: Buffer Lists313708 -Node: Markers and Extents315659 -Node: Bufbytes and Emchars317924 -Node: The Buffer Object318139 -Node: MULE Character Sets and Encodings321619 -Node: Character Sets322681 -Node: Encodings326124 -Node: Japanese EUC (Extended Unix Code)327191 -Node: JIS7328005 -Node: Internal Mule Encodings329355 -Node: Internal String Encoding331185 -Node: Internal Character Encoding333298 -Node: CCL335022 -Node: The Lisp Reader and Compiler341775 -Node: Lstreams341988 -Node: Creating an Lstream343019 -Node: Lstream Types344229 -Node: Lstream Functions344482 -Node: Lstream Methods348048 -Node: Consoles; Devices; Frames; Windows351190 -Node: Introduction to Consoles; Devices; Frames; Windows351505 -Node: Point353995 -Node: Window Hierarchy355274 -Node: The Window Object359726 -Node: The Redisplay Mechanism363163 -Node: Critical Redisplay Sections363955 -Node: Line Start Cache364910 -Node: Redisplay Piece by Piece368146 -Node: Extents370183 -Node: Introduction to Extents370717 -Node: Extent Ordering371843 -Node: Format of the Extent Info373084 -Node: Zero-Length Extents374971 -Node: Mathematics of Extent Ordering376371 -Node: Extent Fragments381128 -Node: Faces382214 -Node: Glyphs382330 -Node: Specifiers388963 -Node: Menus389092 -Node: Subprocesses391350 -Node: Interface to the X Window System393336 -Node: Lucid Widget Library393617 -Node: Generic Widget Interface394908 -Node: Scrollbars398467 -Node: Menubars398610 -Node: Checkboxes and Radio Buttons398753 -Node: Progress Bars398939 -Node: Tab Controls399099 -Node: Index399220 +Node: XEmacs18741 +Node: XEmacs From the Outside25850 +Node: The Lisp Language27614 +Node: XEmacs From the Perspective of Building37154 +Node: XEmacs From the Inside43276 +Node: The XEmacs Object System (Abstractly Speaking)51650 +Node: How Lisp Objects Are Represented in C65733 +Node: Rules When Writing New C Code71819 +Node: A Reader's Guide to XEmacs Coding Conventions72715 +Node: General Coding Rules77555 +Node: Writing Lisp Primitives83378 +Node: Writing Good Comments94538 +Node: Adding Global Lisp Variables98074 +Node: Proper Use of Unsigned Types102002 +Node: Coding for Mule103249 +Node: Character-Related Data Types104225 +Node: Working With Character and Byte Positions107195 +Node: Conversion to and from External Data110957 +Node: General Guidelines for Writing Mule-Aware Code117095 +Node: An Example of Mule-Aware Code119780 +Node: Techniques for XEmacs Developers121758 +Node: Regression Testing XEmacs130591 +Node: A Summary of the Various XEmacs Modules135037 +Node: Low-Level Modules135885 +Node: Basic Lisp Modules143298 +Node: Modules for Standard Editing Operations149892 +Node: Editor-Level Control Flow Modules155780 +Node: Modules for the Basic Displayable Lisp Objects159291 +Node: Modules for other Display-Related Lisp Objects162244 +Node: Modules for the Redisplay Mechanism163919 +Node: Modules for Interfacing with the File System166291 +Node: Modules for Other Aspects of the Lisp Interpreter and Object System169989 +Node: Modules for Interfacing with the Operating System176696 +Node: Modules for Interfacing with X Windows184252 +Node: Modules for Internationalization187735 +Node: Modules for Regression Testing190413 +Node: Allocation of Objects in XEmacs Lisp191113 +Node: Introduction to Allocation191634 +Node: Garbage Collection195272 +Node: GCPROing196426 +Node: Garbage Collection - Step by Step203584 +Node: Invocation203976 +Node: garbage_collect_1206944 +Node: mark_object216423 +Node: gc_sweep218232 +Node: sweep_lcrecords_1223293 +Node: compact_string_chars224285 +Node: sweep_strings226462 +Node: sweep_bit_vectors_1227424 +Node: Integers and Characters228097 +Node: Allocation from Frob Blocks228846 +Node: lrecords230447 +Node: Low-level allocation242670 +Node: Cons246774 +Node: Vector247497 +Node: Bit Vector248072 +Node: Symbol248562 +Node: Marker248913 +Node: String249465 +Node: Compiled Function253074 +Node: Dumping253240 +Node: Overview255458 +Node: Data descriptions256009 +Node: Dumping phase258011 +Node: Object inventory258411 +Node: Address allocation261322 +Node: The header262708 +Node: Data dumping263150 +Node: Pointers dumping263808 +Node: Reloading phase265195 +Node: Remaining issues266731 +Node: Events and the Event Loop267689 +Node: Introduction to Events268139 +Node: Main Loop270051 +Node: Specifics of the Event Gathering Mechanism273623 +Node: Specifics About the Emacs Event286073 +Node: The Event Stream Callback Routines286328 +Node: Other Event Loop Functions286573 +Node: Converting Events287710 +Node: Dispatching Events; The Command Builder288316 +Node: Evaluation; Stack Frames; Bindings288548 +Node: Evaluation288890 +Node: Dynamic Binding; The specbinding Stack; Unwind-Protects295399 +Node: Simple Special Forms297783 +Node: Catch and Throw298563 +Node: Symbols and Variables301138 +Node: Introduction to Symbols301402 +Node: Obarrays302437 +Node: Symbol Values305967 +Node: Buffers and Textual Representation308252 +Node: Introduction to Buffers308910 +Node: The Text in a Buffer311570 +Node: Buffer Lists318716 +Node: Markers and Extents320664 +Node: Bufbytes and Emchars322926 +Node: The Buffer Object323138 +Node: MULE Character Sets and Encodings326613 +Node: Character Sets327672 +Node: Encodings331112 +Node: Japanese EUC (Extended Unix Code)332176 +Node: JIS7332987 +Node: Internal Mule Encodings334334 +Node: Internal String Encoding336162 +Node: Internal Character Encoding338273 +Node: CCL339994 +Node: The Lisp Reader and Compiler346747 +Node: Lstreams346957 +Node: Creating an Lstream347985 +Node: Lstream Types349192 +Node: Lstream Functions349445 +Node: Lstream Methods353011 +Node: Consoles; Devices; Frames; Windows356153 +Node: Introduction to Consoles; Devices; Frames; Windows356468 +Node: Point358955 +Node: Window Hierarchy360231 +Node: The Window Object364680 +Node: The Redisplay Mechanism368114 +Node: Critical Redisplay Sections368903 +Node: Line Start Cache369855 +Node: Redisplay Piece by Piece373088 +Node: Extents375122 +Node: Introduction to Extents375656 +Node: Extent Ordering376779 +Node: Format of the Extent Info378017 +Node: Zero-Length Extents379901 +Node: Mathematics of Extent Ordering381297 +Node: Extent Fragments386052 +Node: Faces387135 +Node: Glyphs387248 +Node: Specifiers393869 +Node: Menus393995 +Node: Subprocesses396250 +Node: Interface to the X Window System398233 +Node: Lucid Widget Library398511 +Node: Generic Widget Interface399799 +Node: Scrollbars403355 +Node: Menubars403498 +Node: Checkboxes and Radio Buttons403641 +Node: Progress Bars403827 +Node: Tab Controls403987 +Node: Index404108  End Tag Table diff -u -r -N xemacs-21.4.14/info/internals.info-1 xemacs-21.4.15/info/internals.info-1 --- xemacs-21.4.14/info/internals.info-1 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-1 2004-02-02 22:01:07.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from +This is ../info/internals.info, produced by makeinfo version 4.6 from internals/internals.texi. INFO-DIR-SECTION XEmacs Editor @@ -7,8 +7,9 @@ END-INFO-DIR-ENTRY Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. +Microsystems. Copyright (C) 1994 - 1998, 2002, 2003 Free Software +Foundation. Copyright (C) 1994, 1995 Board of Trustees, University of +Illinois. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -249,7 +250,7 @@ A History of Emacs ****************** - XEmacs is a powerful, customizable text editor and development +XEmacs is a powerful, customizable text editor and development environment. It began as Lucid Emacs, which was in turn derived from GNU Emacs, a program written by Richard Stallman of the Free Software Foundation. GNU Emacs dates back to the 1970's, and was modelled after @@ -280,8 +281,8 @@ Through Version 18 ================== - Although the history of the early versions of GNU Emacs is unclear, -the history is well-known from the middle of 1985. A time line is: +Although the history of the early versions of GNU Emacs is unclear, the +history is well-known from the middle of 1985. A time line is: * GNU Emacs version 15 (15.34) was released sometime in 1984 or 1985 and shared some code with a version of Emacs written by James @@ -392,7 +393,7 @@ Lucid Emacs =========== - Lucid Emacs was developed by the (now-defunct) Lucid Inc., a maker of +Lucid Emacs was developed by the (now-defunct) Lucid Inc., a maker of C++ and Lisp development environments. It began when Lucid decided they wanted to use Emacs as the editor and cornerstone of their C++ development environment (called "Energize"). They needed many features @@ -505,11 +506,11 @@ GNU Emacs 19 ============ - About a year after the initial release of Lucid Emacs, the FSF -released a beta of their version of Emacs 19 (referred to here as "GNU -Emacs"). By this time, the current version of Lucid Emacs was 19.6. -(Strangely, the first released beta from the FSF was GNU Emacs 19.7.) A -time line for GNU Emacs version 19 is +About a year after the initial release of Lucid Emacs, the FSF released +a beta of their version of Emacs 19 (referred to here as "GNU Emacs"). +By this time, the current version of Lucid Emacs was 19.6. (Strangely, +the first released beta from the FSF was GNU Emacs 19.7.) A time line +for GNU Emacs version 19 is * version 19.8 (beta) released May 27, 1993. @@ -579,7 +580,7 @@ GNU Emacs 20 ============ - On February 2, 1997 work began on GNU Emacs to integrate Mule. The +On February 2, 1997 work began on GNU Emacs to integrate Mule. The first release was made in September of that year. A timeline for Emacs 20 is @@ -596,7 +597,7 @@ XEmacs ====== - Around the time that Lucid was developing Energize, Sun Microsystems +Around the time that Lucid was developing Energize, Sun Microsystems was developing their own development environment (called "SPARCWorks") and also decided to use Emacs. They joined forces with the Epoch team at the University of Illinois and later with Lucid. The maintainer of @@ -802,7 +803,7 @@ XEmacs From the Outside *********************** - XEmacs appears to the outside world as an editor, but it is really a +XEmacs appears to the outside world as an editor, but it is really a Lisp environment. At its heart is a Lisp interpreter; it also "happens" to contain many specialized object types (e.g. buffers, windows, frames, events) that are useful for implementing an editor. @@ -840,7 +841,7 @@ The Lisp Language ***************** - Lisp is a general-purpose language that is higher-level than C and in +Lisp is a general-purpose language that is higher-level than C and in many ways more powerful than C. Powerful dialects of Lisp such as Common Lisp are probably much better languages for writing very large applications than is C. (Unfortunately, for many non-technical reasons @@ -1031,7 +1032,7 @@ XEmacs From the Perspective of Building *************************************** - The heart of XEmacs is the Lisp environment, which is written in C. +The heart of XEmacs is the Lisp environment, which is written in C. This is contained in the `src/' subdirectory. Underneath `src/' are two subdirectories of header files: `s/' (header files for particular operating systems) and `m/' (header files for particular machine @@ -1140,7 +1141,7 @@ XEmacs From the Inside ********************** - Internally, XEmacs is quite complex, and can be very confusing. To +Internally, XEmacs is quite complex, and can be very confusing. To simplify things, it can be useful to think of XEmacs as containing an event loop that "drives" everything, and a number of other subsystems, such as a Lisp engine and a redisplay mechanism. Each of these other @@ -1286,3 +1287,5490 @@ of obscure and unwanted interactions occurring than if they were to change the C code. + +File: internals.info, Node: The XEmacs Object System (Abstractly Speaking), Next: How Lisp Objects Are Represented in C, Prev: XEmacs From the Inside, Up: Top + +The XEmacs Object System (Abstractly Speaking) +********************************************** + +At the heart of the Lisp interpreter is its management of objects. +XEmacs Lisp contains many built-in objects, some of which are simple +and others of which can be very complex; and some of which are very +common, and others of which are rarely used or are only used +internally. (Since the Lisp allocation system, with its automatic +reclamation of unused storage, is so much more convenient than +`malloc()' and `free()', the C code makes extensive use of it in its +internal operations.) + + The basic Lisp objects are + +`integer' + 28 or 31 bits of precision, or 60 or 63 bits on 64-bit machines; + the reason for this is described below when the internal Lisp + object representation is described. + +`float' + Same precision as a double in C. + +`cons' + A simple container for two Lisp objects, used to implement lists + and most other data structures in Lisp. + +`char' + An object representing a single character of text; chars behave + like integers in many ways but are logically considered text + rather than numbers and have a different read syntax. (the read + syntax for a char contains the char itself or some textual + encoding of it--for example, a Japanese Kanji character might be + encoded as `^[$(B#&^[(B' using the ISO-2022 encoding + standard--rather than the numerical representation of the char; + this way, if the mapping between chars and integers changes, which + is quite possible for Kanji characters and other extended + characters, the same character will still be created. Note that + some primitives confuse chars and integers. The worst culprit is + `eq', which makes a special exception and considers a char to be + `eq' to its integer equivalent, even though in no other case are + objects of two different types `eq'. The reason for this + monstrosity is compatibility with existing code; the separation of + char from integer came fairly recently.) + +`symbol' + An object that contains Lisp objects and is referred to by name; + symbols are used to implement variables and named functions and to + provide the equivalent of preprocessor constants in C. + +`vector' + A one-dimensional array of Lisp objects providing constant-time + access to any of the objects; access to an arbitrary object in a + vector is faster than for lists, but the operations that can be + done on a vector are more limited. + +`string' + Self-explanatory; behaves much like a vector of chars but has a + different read syntax and is stored and manipulated more compactly. + +`bit-vector' + A vector of bits; similar to a string in spirit. + +`compiled-function' + An object containing compiled Lisp code, known as "byte code". + +`subr' + A Lisp primitive, i.e. a Lisp-callable function implemented in C. + + Note that there is no basic "function" type, as in more powerful +versions of Lisp (where it's called a "closure"). XEmacs Lisp does not +provide the closure semantics implemented by Common Lisp and Scheme. +The guts of a function in XEmacs Lisp are represented in one of four +ways: a symbol specifying another function (when one function is an +alias for another), a list (whose first element must be the symbol +`lambda') containing the function's source code, a compiled-function +object, or a subr object. (In other words, given a symbol specifying +the name of a function, calling `symbol-function' to retrieve the +contents of the symbol's function cell will return one of these types +of objects.) + + XEmacs Lisp also contains numerous specialized objects used to +implement the editor: + +`buffer' + Stores text like a string, but is optimized for insertion and + deletion and has certain other properties that can be set. + +`frame' + An object with various properties whose displayable representation + is a "window" in window-system parlance. + +`window' + A section of a frame that displays the contents of a buffer; often + called a "pane" in window-system parlance. + +`window-configuration' + An object that represents a saved configuration of windows in a + frame. + +`device' + An object representing a screen on which frames can be displayed; + equivalent to a "display" in the X Window System and a "TTY" in + character mode. + +`face' + An object specifying the appearance of text or graphics; it has + properties such as font, foreground color, and background color. + +`marker' + An object that refers to a particular position in a buffer and + moves around as text is inserted and deleted to stay in the same + relative position to the text around it. + +`extent' + Similar to a marker but covers a range of text in a buffer; can + also specify properties of the text, such as a face in which the + text is to be displayed, whether the text is invisible or + unmodifiable, etc. + +`event' + Generated by calling `next-event' and contains information + describing a particular event happening in the system, such as the + user pressing a key or a process terminating. + +`keymap' + An object that maps from events (described using lists, vectors, + and symbols rather than with an event object because the mapping + is for classes of events, rather than individual events) to + functions to execute or other events to recursively look up; the + functions are described by name, using a symbol, or using lists to + specify the function's code. + +`glyph' + An object that describes the appearance of an image (e.g. pixmap) + on the screen; glyphs can be attached to the beginning or end of + extents and in some future version of XEmacs will be able to be + inserted directly into a buffer. + +`process' + An object that describes a connection to an externally-running + process. + + There are some other, less-commonly-encountered general objects: + +`hash-table' + An object that maps from an arbitrary Lisp object to another + arbitrary Lisp object, using hashing for fast lookup. + +`obarray' + A limited form of hash-table that maps from strings to symbols; + obarrays are used to look up a symbol given its name and are not + actually their own object type but are kludgily represented using + vectors with hidden fields (this representation derives from GNU + Emacs). + +`specifier' + A complex object used to specify the value of a display property; a + default value is given and different values can be specified for + particular frames, buffers, windows, devices, or classes of device. + +`char-table' + An object that maps from chars or classes of chars to arbitrary + Lisp objects; internally char tables use a complex nested-vector + representation that is optimized to the way characters are + represented as integers. + +`range-table' + An object that maps from ranges of integers to arbitrary Lisp + objects. + + And some strange special-purpose objects: + +`charset' +`coding-system' + Objects used when MULE, or multi-lingual/Asian-language, support is + enabled. + +`color-instance' +`font-instance' +`image-instance' + An object that encapsulates a window-system resource; instances are + mostly used internally but are exposed on the Lisp level for + cleanness of the specifier model and because it's occasionally + useful for Lisp program to create or query the properties of + instances. + +`subwindow' + An object that encapsulate a "subwindow" resource, i.e. a + window-system child window that is drawn into by an external + process; this object should be integrated into the glyph system + but isn't yet, and may change form when this is done. + +`tooltalk-message' +`tooltalk-pattern' + Objects that represent resources used in the ToolTalk interprocess + communication protocol. + +`toolbar-button' + An object used in conjunction with the toolbar. + + And objects that are only used internally: + +`opaque' + A generic object for encapsulating arbitrary memory; this allows + you the generality of `malloc()' and the convenience of the Lisp + object system. + +`lstream' + A buffering I/O stream, used to provide a unified interface to + anything that can accept output or provide input, such as a file + descriptor, a stdio stream, a chunk of memory, a Lisp buffer, a + Lisp string, etc.; it's a Lisp object to make its memory + management more convenient. + +`char-table-entry' + Subsidiary objects in the internal char-table representation. + +`extent-auxiliary' +`menubar-data' +`toolbar-data' + Various special-purpose objects that are basically just used to + encapsulate memory for particular subsystems, similar to the more + general "opaque" object. + +`symbol-value-forward' +`symbol-value-buffer-local' +`symbol-value-varalias' +`symbol-value-lisp-magic' + Special internal-only objects that are placed in the value cell of + a symbol to indicate that there is something special with this + variable - e.g. it has no value, it mirrors another variable, or + it mirrors some C variable; there is really only one kind of + object, called a "symbol-value-magic", but it is sort-of halfway + kludged into semi-different object types. + + Some types of objects are "permanent", meaning that once created, +they do not disappear until explicitly destroyed, using a function such +as `delete-buffer', `delete-window', `delete-frame', etc. Others will +disappear once they are not longer used, through the garbage collection +mechanism. Buffers, frames, windows, devices, and processes are among +the objects that are permanent. Note that some objects can go both +ways: Faces can be created either way; extents are normally permanent, +but detached extents (extents not referring to any text, as happens to +some extents when the text they are referring to is deleted) are +temporary. Note that some permanent objects, such as faces and coding +systems, cannot be deleted. Note also that windows are unique in that +they can be _undeleted_ after having previously been deleted. (This +happens as a result of restoring a window configuration.) + + Note that many types of objects have a "read syntax", i.e. a way of +specifying an object of that type in Lisp code. When you load a Lisp +file, or type in code to be evaluated, what really happens is that the +function `read' is called, which reads some text and creates an object +based on the syntax of that text; then `eval' is called, which possibly +does something special; then this loop repeats until there's no more +text to read. (`eval' only actually does something special with +symbols, which causes the symbol's value to be returned, similar to +referencing a variable; and with conses [i.e. lists], which cause a +function invocation. All other values are returned unchanged.) + + The read syntax + + 17297 + + converts to an integer whose value is 17297. + + 1.983e-4 + + converts to a float whose value is 1.983e-4, or .0001983. + + ?b + + converts to a char that represents the lowercase letter b. + + ?^[$(B#&^[(B + + (where `^[' actually is an `ESC' character) converts to a particular +Kanji character when using an ISO2022-based coding system for input. +(To decode this goo: `ESC' begins an escape sequence; `ESC $ (' is a +class of escape sequences meaning "switch to a 94x94 character set"; +`ESC $ ( B' means "switch to Japanese Kanji"; `#' and `&' collectively +index into a 94-by-94 array of characters [subtract 33 from the ASCII +value of each character to get the corresponding index]; `ESC (' is a +class of escape sequences meaning "switch to a 94 character set"; `ESC +(B' means "switch to US ASCII". It is a coincidence that the letter +`B' is used to denote both Japanese Kanji and US ASCII. If the first +`B' were replaced with an `A', you'd be requesting a Chinese Hanzi +character from the GB2312 character set.) + + "foobar" + + converts to a string. + + foobar + + converts to a symbol whose name is `"foobar"'. This is done by +looking up the string equivalent in the global variable `obarray', +whose contents should be an obarray. If no symbol is found, a new +symbol with the name `"foobar"' is automatically created and added to +`obarray'; this process is called "interning" the symbol. + + (foo . bar) + + converts to a cons cell containing the symbols `foo' and `bar'. + + (1 a 2.5) + + converts to a three-element list containing the specified objects +(note that a list is actually a set of nested conses; see the XEmacs +Lisp Reference). + + [1 a 2.5] + + converts to a three-element vector containing the specified objects. + + #[... ... ... ...] + + converts to a compiled-function object (the actual contents are not +shown since they are not relevant here; look at a file that ends with +`.elc' for examples). + + #*01110110 + + converts to a bit-vector. + + #s(hash-table ... ...) + + converts to a hash table (the actual contents are not shown). + + #s(range-table ... ...) + + converts to a range table (the actual contents are not shown). + + #s(char-table ... ...) + + converts to a char table (the actual contents are not shown). + + Note that the `#s()' syntax is the general syntax for structures, +which are not really implemented in XEmacs Lisp but should be. + + When an object is printed out (using `print' or a related function), +the read syntax is used, so that the same object can be read in again. + + The other objects do not have read syntaxes, usually because it does +not really make sense to create them in this fashion (i.e. processes, +where it doesn't make sense to have a subprocess created as a side +effect of reading some Lisp code), or because they can't be created at +all (e.g. subrs). Permanent objects, as a rule, do not have a read +syntax; nor do most complex objects, which contain too much state to be +easily initialized through a read syntax. + + +File: internals.info, Node: How Lisp Objects Are Represented in C, Next: Rules When Writing New C Code, Prev: The XEmacs Object System (Abstractly Speaking), Up: Top + +How Lisp Objects Are Represented in C +************************************* + +Lisp objects are represented in C using a 32-bit or 64-bit machine word +(depending on the processor; i.e. DEC Alphas use 64-bit Lisp objects and +most other processors use 32-bit Lisp objects). The representation +stuffs a pointer together with a tag, as follows: + + [ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ] + [ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ] + + <---------------------------------------------------------> <-> + a pointer to a structure, or an integer tag + + A tag of 00 is used for all pointer object types, a tag of 10 is used +for characters, and the other two tags 01 and 11 are joined together to +form the integer object type. This representation gives us 31 bit +integers and 30 bit characters, while pointers are represented directly +without any bit masking or shifting. This representation, though, +assumes that pointers to structs are always aligned to multiples of 4, +so the lower 2 bits are always zero. + + Lisp objects use the typedef `Lisp_Object', but the actual C type +used for the Lisp object can vary. It can be either a simple type +(`long' on the DEC Alpha, `int' on other machines) or a structure whose +fields are bit fields that line up properly (actually, a union of +structures is used). The choice of which type to use is determined by +the preprocessor constant `USE_UNION_TYPE' which is defined via the +`--use-union-type' option to `configure'. + + Generally the simple integral type is preferable because it ensures +that the compiler will actually use a machine word to represent the +object (some compilers will use more general and less efficient code +for unions and structs even if they can fit in a machine word). The +union type, however, has the advantage of stricter _static_ type +checking. Places where a `Lisp_Object' is mistakenly passed to a +routine expecting an `int' (or vice-versa), or a check is written `if +(foo)' (instead of `if (!NILP (foo))', will be flagged as errors. None +of these lead to the expected results! `Qnil' is not represented as 0 +(so `if (foo)' will *ALWAYS* be true for a `Lisp_Object'), and the +representation of an integer as a `Lisp_Object' is not just the +integer's numeric value, but usually 2x the integer +/- 1.) + + There used to be a claim that the union type simplified debugging. +There may have been a grain of truth to this pre-19.8, when there was no +`lrecord' type and all objects had a separate type appearing in the +tag. Nowadays, however, there is no debugging gain, and in fact +frequent debugging *_loss_*, since many debuggers don't handle unions +very well, and usually there is no way to directly specify a union from +a debugging prompt. + + Furthermore, release builds should *_not_* be done with union type +because (a) you may get less efficiency, with compilers that can't +figure out how to optimize the union into a machine word; (b) even +worse, the union type often triggers miscompilation, especially when +combined with Mule and error-checking. This has been the case at +various times when using GCC and MS VC, at least with `--pdump'. +Therefore, be warned! + + As of 2002 4Q, miscompilation is known to happen with current +versions of *Microsoft VC++* and *GCC in combination with Mule, pdump, +and KKCC* (no error checking). + + Various macros are used to convert between Lisp_Objects and the +corresponding C type. Macros of the form `XINT()', `XCHAR()', +`XSTRING()', `XSYMBOL()', do any required bit shifting and/or masking +and cast it to the appropriate type. `XINT()' needs to be a bit tricky +so that negative numbers are properly sign-extended. Since integers +are stored left-shifted, if the right-shift operator does an arithmetic +shift (i.e. it leaves the most-significant bit as-is rather than +shifting in a zero, so that it mimics a divide-by-two even for negative +numbers) the shift to remove the tag bit is enough. This is the case +on all the systems we support. + + Note that when `ERROR_CHECK_TYPECHECK' is defined, the converter +macros become more complicated--they check the tag bits and/or the type +field in the first four bytes of a record type to ensure that the +object is really of the correct type. This is great for catching places +where an incorrect type is being dereferenced--this typically results +in a pointer being dereferenced as the wrong type of structure, with +unpredictable (and sometimes not easily traceable) results. + + There are similar `XSETTYPE()' macros that construct a Lisp object. +These macros are of the form `XSETTYPE (LVALUE, RESULT)', i.e. they +have to be a statement rather than just used in an expression. The +reason for this is that standard C doesn't let you "construct" a +structure (but GCC does). Granted, this sometimes isn't too +convenient; for the case of integers, at least, you can use the +function `make_int()', which constructs and _returns_ an integer Lisp +object. Note that the `XSETTYPE()' macros are also affected by +`ERROR_CHECK_TYPECHECK' and make sure that the structure is of the +right type in the case of record types, where the type is contained in +the structure. + + The C programmer is responsible for *guaranteeing* that a +Lisp_Object is the correct type before using the `XTYPE' macros. This +is especially important in the case of lists. Use `XCAR' and `XCDR' if +a Lisp_Object is certainly a cons cell, else use `Fcar()' and `Fcdr()'. +Trust other C code, but not Lisp code. On the other hand, if XEmacs +has an internal logic error, it's better to crash immediately, so +sprinkle `assert()'s and "unreachable" `abort()'s liberally about the +source code. Where performance is an issue, use `type_checking_assert', +`bufpos_checking_assert', and `gc_checking_assert', which do nothing +unless the corresponding configure error checking flag was specified. + + +File: internals.info, Node: Rules When Writing New C Code, Next: Regression Testing XEmacs, Prev: How Lisp Objects Are Represented in C, Up: Top + +Rules When Writing New C Code +***************************** + +The XEmacs C Code is extremely complex and intricate, and there are many +rules that are more or less consistently followed throughout the code. +Many of these rules are not obvious, so they are explained here. It is +of the utmost importance that you follow them. If you don't, you may +get something that appears to work, but which will crash in odd +situations, often in code far away from where the actual breakage is. + +* Menu: + +* A Reader's Guide to XEmacs Coding Conventions:: +* General Coding Rules:: +* Writing Lisp Primitives:: +* Writing Good Comments:: +* Adding Global Lisp Variables:: +* Proper Use of Unsigned Types:: +* Coding for Mule:: +* Techniques for XEmacs Developers:: + + +File: internals.info, Node: A Reader's Guide to XEmacs Coding Conventions, Next: General Coding Rules, Up: Rules When Writing New C Code + +A Reader's Guide to XEmacs Coding Conventions +============================================= + +Of course the low-level implementation language of XEmacs is C, but much +of that uses the Lisp engine to do its work. However, because the code +is "inside" of the protective containment shell around the "reactor +core," you'll see lots of complex "plumbing" needed to do the work and +"safety mechanisms," whose failure results in a meltdown. This section +provides a quick overview (or review) of the various components of the +implementation of Lisp objects. + + Two typographic conventions help to identify C objects that implement +Lisp objects. The first is that capitalized identifiers, especially +beginning with the letters `Q', `V', `F', and `S', for C variables and +functions, and C macros with beginning with the letter `X', are used to +implement Lisp. The second is that where Lisp uses the hyphen `-' in +symbol names, the corresponding C identifiers use the underscore `_'. +Of course, since XEmacs Lisp contains interfaces to many external +libraries, those external names will follow the coding conventions +their authors chose, and may overlap the "XEmacs name space." However +these cases are usually pretty obvious. + + All Lisp objects are handled indirectly. The `Lisp_Object' type is +usually a pointer to a structure, except for a very small number of +types with immediate representations (currently characters and +integers). However, these types cannot be directly operated on in C +code, either, so they can also be considered indirect. Types that do +not have an immediate representation always have a C typedef +`Lisp_TYPE' for a corresponding structure. + + In older code, it was common practice to pass around pointers to +`Lisp_TYPE', but this is now deprecated in favor of using `Lisp_Object' +for all function arguments and return values that are Lisp objects. +The `XTYPE' macro is used to extract the pointer and cast it to +`(Lisp_TYPE *)' for the desired type. + + *Convention*: macros whose names begin with `X' operate on +`Lisp_Object's and do no type-checking. Many such macros are type +extractors, but others implement Lisp operations in C (_e.g._, `XCAR' +implements the Lisp `car' function). These are unsafe, and must only +be used where types of all data have already been checked. Such macros +are only applied to `Lisp_Object's. In internal implementations where +the pointer has already been converted, the structure is operated on +directly using the C `->' member access operator. + + The `TYPEP', `CHECK_TYPE', and `CONCHECK_TYPE' macros are used to +test types. The first returns a Boolean value, and the latter signal +errors. (The `CONCHECK' variety allows execution to be CONtinued under +some circumstances, thus the name.) Functions which expect to be +passed user data invariably call `CHECK' macros on arguments. + + There are many types of specialized Lisp objects implemented in C, +but the most pervasive type is the "symbol". Symbols are used as +identifiers, variables, and functions. + + *Convention*: Global variables whose names begin with `Q' are +constants whose value is a symbol. The name of the variable should be +derived from the name of the symbol using the same rules as for Lisp +primitives. Such variables allow the C code to check whether a +particular `Lisp_Object' is equal to a given symbol. Symbols are Lisp +objects, so these variables may be passed to Lisp primitives. (An +alternative to the use of `Q...' variables is to call the `intern' +function at initialization in the `vars_of_MODULE' function, which is +hardly less efficient.) + + *Convention*: Global variables whose names begin with `V' are +variables that contain Lisp objects. The convention here is that all +global variables of type `Lisp_Object' begin with `V', and no others do +(not even integer and boolean variables that have Lisp equivalents). +Most of the time, these variables have equivalents in Lisp, which are +defined via the `DEFVAR' family of macros, but some don't. Since the +variable's value is a `Lisp_Object', it can be passed to Lisp +primitives. + + The implementation of Lisp primitives is more complex. +*Convention*: Global variables with names beginning with `S' contain a +structure that allows the Lisp engine to identify and call a C +function. In modern versions of XEmacs, these identifiers are almost +always completely hidden in the `DEFUN' and `SUBR' macros, but you will +encounter them if you look at very old versions of XEmacs or at GNU +Emacs. *Convention*: Functions with names beginning with `F' implement +Lisp primitives. Of course all their arguments and their return values +must be Lisp_Objects. (This is hidden in the `DEFUN' macro.) + + +File: internals.info, Node: General Coding Rules, Next: Writing Lisp Primitives, Prev: A Reader's Guide to XEmacs Coding Conventions, Up: Rules When Writing New C Code + +General Coding Rules +==================== + +The C code is actually written in a dialect of C called "Clean C", +meaning that it can be compiled, mostly warning-free, with either a C or +C++ compiler. Coding in Clean C has several advantages over plain C. +C++ compilers are more nit-picking, and a number of coding errors have +been found by compiling with C++. The ability to use both C and C++ +tools means that a greater variety of development tools are available to +the developer. + + Every module includes `' (angle brackets so that +`--srcdir' works correctly; `config.h' may or may not be in the same +directory as the C sources) and `lisp.h'. `config.h' must always be +included before any other header files (including system header files) +to ensure that certain tricks played by various `s/' and `m/' files +work out correctly. + + When including header files, always use angle brackets, not double +quotes, except when the file to be included is always in the same +directory as the including file. If either file is a generated file, +then that is not likely to be the case. In order to understand why we +have this rule, imagine what happens when you do a build in the source +directory using `./configure' and another build in another directory +using `../work/configure'. There will be two different `config.h' +files. Which one will be used if you `#include "config.h"'? + + Almost every module contains a `syms_of_*()' function and a +`vars_of_*()' function. The former declares any Lisp primitives you +have defined and defines any symbols you will be using. The latter +declares any global Lisp variables you have added and initializes global +C variables in the module. *Important*: There are stringent +requirements on exactly what can go into these functions. See the +comment in `emacs.c'. The reason for this is to avoid obscure unwanted +interactions during initialization. If you don't follow these rules, +you'll be sorry! If you want to do anything that isn't allowed, create +a `complex_vars_of_*()' function for it. Doing this is tricky, though: +you have to make sure your function is called at the right time so that +all the initialization dependencies work out. + + Declare each function of these kinds in `symsinit.h'. Make sure +it's called in the appropriate place in `emacs.c'. You never need to +include `symsinit.h' directly, because it is included by `lisp.h'. + + *All global and static variables that are to be modifiable must be +declared uninitialized.* This means that you may not use the "declare +with initializer" form for these variables, such as `int some_variable += 0;'. The reason for this has to do with some kludges done during the +dumping process: If possible, the initialized data segment is re-mapped +so that it becomes part of the (unmodifiable) code segment in the +dumped executable. This allows this memory to be shared among multiple +running XEmacs processes. XEmacs is careful to place as much constant +data as possible into initialized variables during the `temacs' phase. + + *Please note:* This kludge only works on a few systems nowadays, and +is rapidly becoming irrelevant because most modern operating systems +provide "copy-on-write" semantics. All data is initially shared +between processes, and a private copy is automatically made (on a +page-by-page basis) when a process first attempts to write to a page of +memory. + + Formerly, there was a requirement that static variables not be +declared inside of functions. This had to do with another hack along +the same vein as what was just described: old USG systems put +statically-declared variables in the initialized data space, so those +header files had a `#define static' declaration. (That way, the +data-segment remapping described above could still work.) This fails +badly on static variables inside of functions, which suddenly become +automatic variables; therefore, you weren't supposed to have any of +them. This awful kludge has been removed in XEmacs because + + 1. almost all of the systems that used this kludge ended up having to + disable the data-segment remapping anyway; + + 2. the only systems that didn't were extremely outdated ones; + + 3. this hack completely messed up inline functions. + + The C source code makes heavy use of C preprocessor macros. One +popular macro style is: + + #define FOO(var, value) do { \ + Lisp_Object FOO_value = (value); \ + ... /* compute using FOO_value */ \ + (var) = bar; \ + } while (0) + + The `do {...} while (0)' is a standard trick to allow FOO to have +statement semantics, so that it can safely be used within an `if' +statement in C, for example. Multiple evaluation is prevented by +copying a supplied argument into a local variable, so that +`FOO(var,fun(1))' only calls `fun' once. + + Lisp lists are popular data structures in the C code as well as in +Elisp. There are two sets of macros that iterate over lists. +`EXTERNAL_LIST_LOOP_N' should be used when the list has been supplied +by the user, and cannot be trusted to be acyclic and `nil'-terminated. +A `malformed-list' or `circular-list' error will be generated if the +list being iterated over is not entirely kosher. `LIST_LOOP_N', on the +other hand, is faster and less safe, and can be used only on trusted +lists. + + Related macros are `GET_EXTERNAL_LIST_LENGTH' and `GET_LIST_LENGTH', +which calculate the length of a list, and in the case of +`GET_EXTERNAL_LIST_LENGTH', validating the properness of the list. The +macros `EXTERNAL_LIST_LOOP_DELETE_IF' and `LIST_LOOP_DELETE_IF' delete +elements from a lisp list satisfying some predicate. + + +File: internals.info, Node: Writing Lisp Primitives, Next: Writing Good Comments, Prev: General Coding Rules, Up: Rules When Writing New C Code + +Writing Lisp Primitives +======================= + +Lisp primitives are Lisp functions implemented in C. The details of +interfacing the C function so that Lisp can call it are handled by a few +C macros. The only way to really understand how to write new C code is +to read the source, but we can explain some things here. + + An example of a special form is the definition of `prog1', from +`eval.c'. (An ordinary function would have the same general +appearance.) + + DEFUN ("prog1", Fprog1, 1, UNEVALLED, 0, /* + Similar to `progn', but the value of the first form is returned. + \(prog1 FIRST BODY...): All the arguments are evaluated sequentially. + The value of FIRST is saved during evaluation of the remaining args, + whose values are discarded. + */ + (args)) + { + /* This function can GC */ + REGISTER Lisp_Object val, form, tail; + struct gcpro gcpro1; + + val = Feval (XCAR (args)); + + GCPRO1 (val); + + LIST_LOOP_3 (form, XCDR (args), tail) + Feval (form); + + UNGCPRO; + return val; + } + + Let's start with a precise explanation of the arguments to the +`DEFUN' macro. Here is a template for them: + + DEFUN (LNAME, FNAME, MIN_ARGS, MAX_ARGS, INTERACTIVE, /* + DOCSTRING + */ + (ARGLIST)) + +LNAME + This string is the name of the Lisp symbol to define as the + function name; in the example above, it is `"prog1"'. + +FNAME + This is the C function name for this function. This is the name + that is used in C code for calling the function. The name is, by + convention, `F' prepended to the Lisp name, with all dashes (`-') + in the Lisp name changed to underscores. Thus, to call this + function from C code, call `Fprog1'. Remember that the arguments + are of type `Lisp_Object'; various macros and functions for + creating values of type `Lisp_Object' are declared in the file + `lisp.h'. + + Primitives whose names are special characters (e.g. `+' or `<') + are named by spelling out, in some fashion, the special character: + e.g. `Fplus()' or `Flss()'. Primitives whose names begin with + normal alphanumeric characters but also contain special characters + are spelled out in some creative way, e.g. `let*' becomes + `FletX()'. + + Each function also has an associated structure that holds the data + for the subr object that represents the function in Lisp. This + structure conveys the Lisp symbol name to the initialization + routine that will create the symbol and store the subr object as + its definition. The C variable name of this structure is always + `S' prepended to the FNAME. You hardly ever need to be aware of + the existence of this structure, since `DEFUN' plus `DEFSUBR' + takes care of all the details. + +MIN_ARGS + This is the minimum number of arguments that the function + requires. The function `prog1' allows a minimum of one argument. + +MAX_ARGS + This is the maximum number of arguments that the function accepts, + if there is a fixed maximum. Alternatively, it can be `UNEVALLED', + indicating a special form that receives unevaluated arguments, or + `MANY', indicating an unlimited number of evaluated arguments (the + C equivalent of `&rest'). Both `UNEVALLED' and `MANY' are macros. + If MAX_ARGS is a number, it may not be less than MIN_ARGS and it + may not be greater than 8. (If you need to add a function with + more than 8 arguments, use the `MANY' form. Resist the urge to + edit the definition of `DEFUN' in `lisp.h'. If you do it anyways, + make sure to also add another clause to the switch statement in + `primitive_funcall().') + +INTERACTIVE + This is an interactive specification, a string such as might be + used as the argument of `interactive' in a Lisp function. In the + case of `prog1', it is 0 (a null pointer), indicating that `prog1' + cannot be called interactively. A value of `""' indicates a + function that should receive no arguments when called + interactively. + +DOCSTRING + This is the documentation string. It is written just like a + documentation string for a function defined in Lisp; in + particular, the first line should be a single sentence. Note how + the documentation string is enclosed in a comment, none of the + documentation is placed on the same lines as the comment-start and + comment-end characters, and the comment-start characters are on + the same line as the interactive specification. `make-docfile', + which scans the C files for documentation strings, is very + particular about what it looks for, and will not properly extract + the doc string if it's not in this exact format. + + In order to make both `etags' and `make-docfile' happy, make sure + that the `DEFUN' line contains the LNAME and FNAME, and that the + comment-start characters for the doc string are on the same line + as the interactive specification, and put a newline directly after + them (and before the comment-end characters). + +ARGLIST + This is the comma-separated list of arguments to the C function. + For a function with a fixed maximum number of arguments, provide a + C argument for each Lisp argument. In this case, unlike regular C + functions, the types of the arguments are not declared; they are + simply always of type `Lisp_Object'. + + The names of the C arguments will be used as the names of the + arguments to the Lisp primitive as displayed in its documentation, + modulo the same concerns described above for `F...' names (in + particular, underscores in the C arguments become dashes in the + Lisp arguments). + + There is one additional kludge: A trailing `_' on the C argument is + discarded when forming the Lisp argument. This allows C language + reserved words (like `default') or global symbols (like `dirname') + to be used as argument names without compiler warnings or errors. + + A Lisp function with MAX_ARGS = `UNEVALLED' is a "special form"; + its arguments are not evaluated. Instead it receives one argument + of type `Lisp_Object', a (Lisp) list of the unevaluated arguments, + conventionally named `(args)'. + + When a Lisp function has no upper limit on the number of arguments, + specify MAX_ARGS = `MANY'. In this case its implementation in C + actually receives exactly two arguments: the number of Lisp + arguments (an `int') and the address of a block containing their + values (a `Lisp_Object *'). In this case only are the C types + specified in the ARGLIST: `(int nargs, Lisp_Object *args)'. + + + Within the function `Fprog1' itself, note the use of the macros +`GCPRO1' and `UNGCPRO'. `GCPRO1' is used to "protect" a variable from +garbage collection--to inform the garbage collector that it must look +in that variable and regard the object pointed at by its contents as an +accessible object. This is necessary whenever you call `Feval' or +anything that can directly or indirectly call `Feval' (this includes +the `QUIT' macro!). At such a time, any Lisp object that you intend to +refer to again must be protected somehow. `UNGCPRO' cancels the +protection of the variables that are protected in the current function. +It is necessary to do this explicitly. + + The macro `GCPRO1' protects just one local variable. If you want to +protect two, use `GCPRO2' instead; repeating `GCPRO1' will not work. +Macros `GCPRO3' and `GCPRO4' also exist. + + These macros implicitly use local variables such as `gcpro1'; you +must declare these explicitly, with type `struct gcpro'. Thus, if you +use `GCPRO2', you must declare `gcpro1' and `gcpro2'. + + Note also that the general rule is "caller-protects"; i.e. you are +only responsible for protecting those Lisp objects that you create. Any +objects passed to you as arguments should have been protected by whoever +created them, so you don't in general have to protect them. + + In particular, the arguments to any Lisp primitive are always +automatically `GCPRO'ed, when called "normally" from Lisp code or +bytecode. So only a few Lisp primitives that are called frequently from +C code, such as `Fprogn' protect their arguments as a service to their +caller. You don't need to protect your arguments when writing a new +`DEFUN'. + + `GCPRO'ing is perhaps the trickiest and most error-prone part of +XEmacs coding. It is *extremely* important that you get this right and +use a great deal of discipline when writing this code. *Note +`GCPRO'ing: GCPROing, for full details on how to do this. + + What `DEFUN' actually does is declare a global structure of type +`Lisp_Subr' whose name begins with capital `SF' and which contains +information about the primitive (e.g. a pointer to the function, its +minimum and maximum allowed arguments, a string describing its Lisp +name); `DEFUN' then begins a normal C function declaration using the +`F...' name. The Lisp subr object that is the function definition of a +primitive (i.e. the object in the function slot of the symbol that +names the primitive) actually points to this `SF' structure; when +`Feval' encounters a subr, it looks in the structure to find out how to +call the C function. + + Defining the C function is not enough to make a Lisp primitive +available; you must also create the Lisp symbol for the primitive (the +symbol is "interned"; *note Obarrays::) and store a suitable subr +object in its function cell. (If you don't do this, the primitive won't +be seen by Lisp code.) The code looks like this: + + DEFSUBR (FNAME); + +Here FNAME is the same name you used as the second argument to `DEFUN'. + + This call to `DEFSUBR' should go in the `syms_of_*()' function at +the end of the module. If no such function exists, create it and make +sure to also declare it in `symsinit.h' and call it from the +appropriate spot in `main()'. *Note General Coding Rules::. + + Note that C code cannot call functions by name unless they are +defined in C. The way to call a function written in Lisp from C is to +use `Ffuncall', which embodies the Lisp function `funcall'. Since the +Lisp function `funcall' accepts an unlimited number of arguments, in C +it takes two: the number of Lisp-level arguments, and a one-dimensional +array containing their values. The first Lisp-level argument is the +Lisp function to call, and the rest are the arguments to pass to it. +Since `Ffuncall' can call the evaluator, you must protect pointers from +garbage collection around the call to `Ffuncall'. (However, `Ffuncall' +explicitly protects all of its parameters, so you don't have to protect +any pointers passed as parameters to it.) + + The C functions `call0', `call1', `call2', and so on, provide handy +ways to call a Lisp function conveniently with a fixed number of +arguments. They work by calling `Ffuncall'. + + `eval.c' is a very good file to look through for examples; `lisp.h' +contains the definitions for important macros and functions. + + +File: internals.info, Node: Writing Good Comments, Next: Adding Global Lisp Variables, Prev: Writing Lisp Primitives, Up: Rules When Writing New C Code + +Writing Good Comments +===================== + +Comments are a lifeline for programmers trying to understand tricky +code. In general, the less obvious it is what you are doing, the more +you need a comment, and the more detailed it needs to be. You should +always be on guard when you're writing code for stuff that's tricky, and +should constantly be putting yourself in someone else's shoes and asking +if that person could figure out without much difficulty what's going +on. (Assume they are a competent programmer who understands the +essentials of how the XEmacs code is structured but doesn't know much +about the module you're working on or any algorithms you're using.) If +you're not sure whether they would be able to, add a comment. Always +err on the side of more comments, rather than less. + + Generally, when making comments, there is no need to attribute them +with your name or initials. This especially goes for small, +easy-to-understand, non-opinionated ones. Also, comments indicating +where, when, and by whom a file was changed are _strongly_ discouraged, +and in general will be removed as they are discovered. This is exactly +what `ChangeLogs' are there for. However, it can occasionally be +useful to mark exactly where (but not when or by whom) changes are +made, particularly when making small changes to a file imported from +elsewhere. These marks help when later on a newer version of the file +is imported and the changes need to be merged. (If everything were +always kept in CVS, there would be no need for this. But in practice, +this often doesn't happen, or the CVS repository is later on lost or +unavailable to the person doing the update.) + + When putting in an explicit opinion in a comment, you should +_always_ attribute it with your name, and optionally the date. This +also goes for long, complex comments explaining in detail the workings +of something - by putting your name there, you make it possible for +someone who has questions about how that thing works to determine who +wrote the comment so they can write to them. Preferably, use your +actual name and not your initials, unless your initials are generally +recognized (e.g. `jwz'). You can use only your first name if it's +obvious who you are; otherwise, give first and last name. If you're +not a regular contributor, you might consider putting your email +address in - it may be in the ChangeLog, but after awhile ChangeLogs +have a tendency of disappearing or getting muddled. (E.g. your comment +may get copied somewhere else or even into another program, and +tracking down the proper ChangeLog may be very difficult.) + + If you come across an opinion that is not or no longer valid, or you +come across any comment that no longer applies but you want to keep it +around, enclose it in `[[ ' and ` ]]' marks and add a comment +afterwards explaining why the preceding comment is no longer valid. Put +your name on this comment, as explained above. + + Just as comments are a lifeline to programmers, incorrect comments +are death. If you come across an incorrect comment, *immediately* +correct it or flag it as incorrect, as described in the previous +paragraph. Whenever you work on a section of code, _always_ make sure +to update any comments to be correct - or, at the very least, flag them +as incorrect. + + To indicate a "todo" or other problem, use four pound signs - i.e. +`####'. + + +File: internals.info, Node: Adding Global Lisp Variables, Next: Proper Use of Unsigned Types, Prev: Writing Good Comments, Up: Rules When Writing New C Code + +Adding Global Lisp Variables +============================ + +Global variables whose names begin with `Q' are constants whose value +is a symbol of a particular name. The name of the variable should be +derived from the name of the symbol using the same rules as for Lisp +primitives. These variables are initialized using a call to +`defsymbol()' in the `syms_of_*()' function. (This call interns a +symbol, sets the C variable to the resulting Lisp object, and calls +`staticpro()' on the C variable to tell the garbage-collection +mechanism about this variable. What `staticpro()' does is add a +pointer to the variable to a large global array; when +garbage-collection happens, all pointers listed in the array are used +as starting points for marking Lisp objects. This is important because +it's quite possible that the only current reference to the object is +the C variable. In the case of symbols, the `staticpro()' doesn't +matter all that much because the symbol is contained in `obarray', +which is itself `staticpro()'ed. However, it's possible that a naughty +user could do something like uninterning the symbol out of `obarray' or +even setting `obarray' to a different value [although this is likely to +make XEmacs crash!].) + + *Please note:* It is potentially deadly if you declare a `Q...' +variable in two different modules. The two calls to `defsymbol()' are +no problem, but some linkers will complain about multiply-defined +symbols. The most insidious aspect of this is that often the link will +succeed anyway, but then the resulting executable will sometimes crash +in obscure ways during certain operations! + + To avoid this problem, declare any symbols with common names (such as +`text') that are not obviously associated with this particular module +in the file `general-slots.h'. The "-slots" suffix indicates that this +is a file that is included multiple times in `general.c'. Redefinition +of preprocessor macros allows the effects to be different in each +context, so this is actually more convenient and less error-prone than +doing it in your module. + + Global variables whose names begin with `V' are variables that +contain Lisp objects. The convention here is that all global variables +of type `Lisp_Object' begin with `V', and all others don't (including +integer and boolean variables that have Lisp equivalents). Most of the +time, these variables have equivalents in Lisp, but some don't. Those +that do are declared this way by a call to `DEFVAR_LISP()' in the +`vars_of_*()' initializer for the module. What this does is create a +special "symbol-value-forward" Lisp object that contains a pointer to +the C variable, intern a symbol whose name is as specified in the call +to `DEFVAR_LISP()', and set its value to the symbol-value-forward Lisp +object; it also calls `staticpro()' on the C variable to tell the +garbage-collection mechanism about the variable. When `eval' (or +actually `symbol-value') encounters this special object in the process +of retrieving a variable's value, it follows the indirection to the C +variable and gets its value. `setq' does similar things so that the C +variable gets changed. + + Whether or not you `DEFVAR_LISP()' a variable, you need to +initialize it in the `vars_of_*()' function; otherwise it will end up +as all zeroes, which is the integer 0 (_not_ `nil'), and this is +probably not what you want. Also, if the variable is not +`DEFVAR_LISP()'ed, *you must call* `staticpro()' on the C variable in +the `vars_of_*()' function. Otherwise, the garbage-collection +mechanism won't know that the object in this variable is in use, and +will happily collect it and reuse its storage for another Lisp object, +and you will be the one who's unhappy when you can't figure out how +your variable got overwritten. + + +File: internals.info, Node: Proper Use of Unsigned Types, Next: Coding for Mule, Prev: Adding Global Lisp Variables, Up: Rules When Writing New C Code + +Proper Use of Unsigned Types +============================ + +Avoid using `unsigned int' and `unsigned long' whenever possible. +Unsigned types are viral - any arithmetic or comparisons involving +mixed signed and unsigned types are automatically converted to +unsigned, which is almost certainly not what you want. Many subtle and +hard-to-find bugs are created by careless use of unsigned types. In +general, you should almost _never_ use an unsigned type to hold a +regular quantity of any sort. The only exceptions are + + 1. When there's a reasonable possibility you will actually need all + 32 or 64 bits to store the quantity. + + 2. When calling existing API's that require unsigned types. In this + case, you should still do all manipulation using signed types, and + do the conversion at the very threshold of the API call. + + 3. In existing code that you don't want to modify because you don't + maintain it. + + 4. In bit-field structures. + + Other reasonable uses of `unsigned int' and `unsigned long' are +representing non-quantities - e.g. bit-oriented flags and such. + + +File: internals.info, Node: Coding for Mule, Next: Techniques for XEmacs Developers, Prev: Proper Use of Unsigned Types, Up: Rules When Writing New C Code + +Coding for Mule +=============== + +Although Mule support is not compiled by default in XEmacs, many people +are using it, and we consider it crucial that new code works correctly +with multibyte characters. This is not hard; it is only a matter of +following several simple user-interface guidelines. Even if you never +compile with Mule, with a little practice you will find it quite easy +to code Mule-correctly. + + Note that these guidelines are not necessarily tied to the current +Mule implementation; they are also a good idea to follow on the grounds +of code generalization for future I18N work. + +* Menu: + +* Character-Related Data Types:: +* Working With Character and Byte Positions:: +* Conversion to and from External Data:: +* General Guidelines for Writing Mule-Aware Code:: +* An Example of Mule-Aware Code:: + + +File: internals.info, Node: Character-Related Data Types, Next: Working With Character and Byte Positions, Up: Coding for Mule + +Character-Related Data Types +---------------------------- + +First, let's review the basic character-related datatypes used by +XEmacs. Note that the separate `typedef's are not mandatory in the +current implementation (all of them boil down to `unsigned char' or +`int'), but they improve clarity of code a great deal, because one +glance at the declaration can tell the intended use of the variable. + +`Emchar' + An `Emchar' holds a single Emacs character. + + Obviously, the equality between characters and bytes is lost in + the Mule world. Characters can be represented by one or more + bytes in the buffer, and `Emchar' is the C type large enough to + hold any character. + + Without Mule support, an `Emchar' is equivalent to an `unsigned + char'. + +`Bufbyte' + The data representing the text in a buffer or string is logically + a set of `Bufbyte's. + + XEmacs does not work with the same character formats all the time; + when reading characters from the outside, it decodes them to an + internal format, and likewise encodes them when writing. + `Bufbyte' (in fact `unsigned char') is the basic unit of XEmacs + internal buffers and strings format. A `Bufbyte *' is the type + that points at text encoded in the variable-width internal + encoding. + + One character can correspond to one or more `Bufbyte's. In the + current Mule implementation, an ASCII character is represented by + the same `Bufbyte', and other characters are represented by a + sequence of two or more `Bufbyte's. + + Without Mule support, there are exactly 256 characters, implicitly + Latin-1, and each character is represented using one `Bufbyte', and + there is a one-to-one correspondence between `Bufbyte's and + `Emchar's. + +`Bufpos' +`Charcount' + A `Bufpos' represents a character position in a buffer or string. + A `Charcount' represents a number (count) of characters. + Logically, subtracting two `Bufpos' values yields a `Charcount' + value. Although all of these are `typedef'ed to `EMACS_INT', we + use them in preference to `EMACS_INT' to make it clear what sort + of position is being used. + + `Bufpos' and `Charcount' values are the only ones that are ever + visible to Lisp. + +`Bytind' +`Bytecount' + A `Bytind' represents a byte position in a buffer or string. A + `Bytecount' represents the distance between two positions, in + bytes. The relationship between `Bytind' and `Bytecount' is the + same as the relationship between `Bufpos' and `Charcount'. + +`Extbyte' +`Extcount' + When dealing with the outside world, XEmacs works with `Extbyte's, + which are equivalent to `unsigned char'. Obviously, an `Extcount' + is the distance between two `Extbyte's. Extbytes and Extcounts + are not all that frequent in XEmacs code. + + +File: internals.info, Node: Working With Character and Byte Positions, Next: Conversion to and from External Data, Prev: Character-Related Data Types, Up: Coding for Mule + +Working With Character and Byte Positions +----------------------------------------- + +Now that we have defined the basic character-related types, we can look +at the macros and functions designed for work with them and for +conversion between them. Most of these macros are defined in +`buffer.h', and we don't discuss all of them here, but only the most +important ones. Examining the existing code is the best way to learn +about them. + +`MAX_EMCHAR_LEN' + This preprocessor constant is the maximum number of buffer bytes to + represent an Emacs character in the variable width internal + encoding. It is useful when allocating temporary strings to keep + a known number of characters. For instance: + + { + Charcount cclen; + ... + { + /* Allocate place for CCLEN characters. */ + Bufbyte *buf = (Bufbyte *)alloca (cclen * MAX_EMCHAR_LEN); + ... + + If you followed the previous section, you can guess that, + logically, multiplying a `Charcount' value with `MAX_EMCHAR_LEN' + produces a `Bytecount' value. + + In the current Mule implementation, `MAX_EMCHAR_LEN' equals 4. + Without Mule, it is 1. + +`charptr_emchar' +`set_charptr_emchar' + The `charptr_emchar' macro takes a `Bufbyte' pointer and returns + the `Emchar' stored at that position. If it were a function, its + prototype would be: + + Emchar charptr_emchar (Bufbyte *p); + + `set_charptr_emchar' stores an `Emchar' to the specified byte + position. It returns the number of bytes stored: + + Bytecount set_charptr_emchar (Bufbyte *p, Emchar c); + + It is important to note that `set_charptr_emchar' is safe only for + appending a character at the end of a buffer, not for overwriting a + character in the middle. This is because the width of characters + varies, and `set_charptr_emchar' cannot resize the string if it + writes, say, a two-byte character where a single-byte character + used to reside. + + A typical use of `set_charptr_emchar' can be demonstrated by this + example, which copies characters from buffer BUF to a temporary + string of Bufbytes. + + { + Bufpos pos; + for (pos = beg; pos < end; pos++) + { + Emchar c = BUF_FETCH_CHAR (buf, pos); + p += set_charptr_emchar (buf, c); + } + } + + Note how `set_charptr_emchar' is used to store the `Emchar' and + increment the counter, at the same time. + +`INC_CHARPTR' +`DEC_CHARPTR' + These two macros increment and decrement a `Bufbyte' pointer, + respectively. They will adjust the pointer by the appropriate + number of bytes according to the byte length of the character + stored there. Both macros assume that the memory address is + located at the beginning of a valid character. + + Without Mule support, `INC_CHARPTR (p)' and `DEC_CHARPTR (p)' + simply expand to `p++' and `p--', respectively. + +`bytecount_to_charcount' + Given a pointer to a text string and a length in bytes, return the + equivalent length in characters. + + Charcount bytecount_to_charcount (Bufbyte *p, Bytecount bc); + +`charcount_to_bytecount' + Given a pointer to a text string and a length in characters, + return the equivalent length in bytes. + + Bytecount charcount_to_bytecount (Bufbyte *p, Charcount cc); + +`charptr_n_addr' + Return a pointer to the beginning of the character offset CC (in + characters) from P. + + Bufbyte *charptr_n_addr (Bufbyte *p, Charcount cc); + + +File: internals.info, Node: Conversion to and from External Data, Next: General Guidelines for Writing Mule-Aware Code, Prev: Working With Character and Byte Positions, Up: Coding for Mule + +Conversion to and from External Data +------------------------------------ + +When an external function, such as a C library function, returns a +`char' pointer, you should almost never treat it as `Bufbyte'. This is +because these returned strings may contain 8bit characters which can be +misinterpreted by XEmacs, and cause a crash. Likewise, when exporting +a piece of internal text to the outside world, you should always +convert it to an appropriate external encoding, lest the internal stuff +(such as the infamous \201 characters) leak out. + + The interface to conversion between the internal and external +representations of text are the numerous conversion macros defined in +`buffer.h'. There used to be a fixed set of external formats supported +by these macros, but now any coding system can be used with these +macros. The coding system alias mechanism is used to create the +following logical coding systems, which replace the fixed external +formats. The (dontusethis-set-symbol-value-handler) mechanism was +enhanced to make this possible (more work on that is needed - like +remove the `dontusethis-' prefix). + +`Qbinary' + This is the simplest format and is what we use in the absence of a + more appropriate format. This converts according to the `binary' + coding system: + + a. On input, bytes 0-255 are converted into (implicitly Latin-1) + characters 0-255. A non-Mule xemacs doesn't really know about + different character sets and the fonts to display them, so + the bytes can be treated as text in different 1-byte + encodings by simply setting the appropriate fonts. So in a + sense, non-Mule xemacs is a multi-lingual editor if, for + example, different fonts are used to display text in + different buffers, faces, or windows. The specifier + mechanism gives the user complete control over this kind of + behavior. + + b. On output, characters 0-255 are converted into bytes 0-255 + and other characters are converted into `~'. + +`Qfile_name' + Format used for filenames. This is user-definable via either the + `file-name-coding-system' or `pathname-coding-system' (now + obsolete) variables. + +`Qnative' + Format used for the external Unix environment--`argv[]', stuff + from `getenv()', stuff from the `/etc/passwd' file, etc. + Currently this is the same as Qfile_name. The two should be + distinguished for clarity and possible future separation. + +`Qctext' + Compound-text format. This is the standard X11 format used for + data stored in properties, selections, and the like. This is an + 8-bit no-lock-shift ISO2022 coding system. This is a real coding + system, unlike Qfile_name, which is user-definable. + + There are two fundamental macros to convert between external and +internal format. + + `TO_INTERNAL_FORMAT' converts external data to internal format, and +`TO_EXTERNAL_FORMAT' converts the other way around. The arguments each +of these receives are a source type, a source, a sink type, a sink, and +a coding system (or a symbol naming a coding system). + + A typical call looks like + TO_EXTERNAL_FORMAT (LISP_STRING, str, C_STRING_MALLOC, ptr, Qfile_name); + + which means that the contents of the lisp string `str' are written +to a malloc'ed memory area which will be pointed to by `ptr', after the +function returns. The conversion will be done using the `file-name' +coding system, which will be controlled by the user indirectly by +setting or binding the variable `file-name-coding-system'. + + Some sources and sinks require two C variables to specify. We use +some preprocessor magic to allow different source and sink types, and +even different numbers of arguments to specify different types of +sources and sinks. + + So we can have a call that looks like + TO_INTERNAL_FORMAT (DATA, (ptr, len), + MALLOC, (ptr, len), + coding_system); + + The parenthesized argument pairs are required to make the +preprocessor magic work. + + Here are the different source and sink types: + +``DATA, (ptr, len),'' + input data is a fixed buffer of size LEN at address PTR + +``ALLOCA, (ptr, len),'' + output data is placed in an alloca()ed buffer of size LEN pointed + to by PTR + +``MALLOC, (ptr, len),'' + output data is in a malloc()ed buffer of size LEN pointed to by PTR + +``C_STRING_ALLOCA, ptr,'' + equivalent to `ALLOCA (ptr, len_ignored)' on output. + +``C_STRING_MALLOC, ptr,'' + equivalent to `MALLOC (ptr, len_ignored)' on output + +``C_STRING, ptr,'' + equivalent to `DATA, (ptr, strlen (ptr) + 1)' on input + +``LISP_STRING, string,'' + input or output is a Lisp_Object of type string + +``LISP_BUFFER, buffer,'' + output is written to `(point)' in lisp buffer BUFFER + +``LISP_LSTREAM, lstream,'' + input or output is a Lisp_Object of type lstream + +``LISP_OPAQUE, object,'' + input or output is a Lisp_Object of type opaque + + Often, the data is being converted to a '\0'-byte-terminated string, +which is the format required by many external system C APIs. For these +purposes, a source type of `C_STRING' or a sink type of +`C_STRING_ALLOCA' or `C_STRING_MALLOC' is appropriate. Otherwise, we +should try to keep XEmacs '\0'-byte-clean, which means using (ptr, len) +pairs. + + The sinks to be specified must be lvalues, unless they are the lisp +object types `LISP_LSTREAM' or `LISP_BUFFER'. + + For the sink types `ALLOCA' and `C_STRING_ALLOCA', the resulting +text is stored in a stack-allocated buffer, which is automatically +freed on returning from the function. However, the sink types `MALLOC' +and `C_STRING_MALLOC' return `xmalloc()'ed memory. The caller is +responsible for freeing this memory using `xfree()'. + + Note that it doesn't make sense for `LISP_STRING' to be a source for +`TO_INTERNAL_FORMAT' or a sink for `TO_EXTERNAL_FORMAT'. You'll get an +assertion failure if you try. + + +File: internals.info, Node: General Guidelines for Writing Mule-Aware Code, Next: An Example of Mule-Aware Code, Prev: Conversion to and from External Data, Up: Coding for Mule + +General Guidelines for Writing Mule-Aware Code +---------------------------------------------- + +This section contains some general guidance on how to write Mule-aware +code, as well as some pitfalls you should avoid. + +_Never use `char' and `char *'._ + In XEmacs, the use of `char' and `char *' is almost always a + mistake. If you want to manipulate an Emacs character from "C", + use `Emchar'. If you want to examine a specific octet in the + internal format, use `Bufbyte'. If you want a Lisp-visible + character, use a `Lisp_Object' and `make_char'. If you want a + pointer to move through the internal text, use `Bufbyte *'. Also + note that you almost certainly do not need `Emchar *'. + +_Be careful not to confuse `Charcount', `Bytecount', and `Bufpos'._ + The whole point of using different types is to avoid confusion + about the use of certain variables. Lest this effect be + nullified, you need to be careful about using the right types. + +_Always convert external data_ + It is extremely important to always convert external data, because + XEmacs can crash if unexpected 8bit sequences are copied to its + internal buffers literally. + + This means that when a system function, such as `readdir', returns + a string, you may need to convert it using one of the conversion + macros described in the previous chapter, before passing it + further to Lisp. + + Actually, most of the basic system functions that accept + '\0'-terminated string arguments, like `stat()' and `open()', have + been *encapsulated* so that they are they `always' do internal to + external conversion themselves. This means you must pass + internally encoded data, typically the `XSTRING_DATA' of a + Lisp_String to these functions. This is actually a design bug, + since it unexpectedly changes the semantics of the system + functions. A better design would be to provide separate versions + of these system functions that accepted Lisp_Objects which were + lisp strings in place of their current `char *' arguments. + + int stat_lisp (Lisp_Object path, struct stat *buf); /* Implement me */ + + Also note that many internal functions, such as `make_string', + accept Bufbytes, which removes the need for them to convert the + data they receive. This increases efficiency because that way + external data needs to be decoded only once, when it is read. + After that, it is passed around in internal format. + + +File: internals.info, Node: An Example of Mule-Aware Code, Prev: General Guidelines for Writing Mule-Aware Code, Up: Coding for Mule + +An Example of Mule-Aware Code +----------------------------- + +As an example of Mule-aware code, we will analyze the `string' +function, which conses up a Lisp string from the character arguments it +receives. Here is the definition, pasted from `alloc.c': + + DEFUN ("string", Fstring, 0, MANY, 0, /* + Concatenate all the argument characters and make the result a string. + */ + (int nargs, Lisp_Object *args)) + { + Bufbyte *storage = alloca_array (Bufbyte, nargs * MAX_EMCHAR_LEN); + Bufbyte *p = storage; + + for (; nargs; nargs--, args++) + { + Lisp_Object lisp_char = *args; + CHECK_CHAR_COERCE_INT (lisp_char); + p += set_charptr_emchar (p, XCHAR (lisp_char)); + } + return make_string (storage, p - storage); + } + + Now we can analyze the source line by line. + + Obviously, string will be as long as there are arguments to the +function. This is why we allocate `MAX_EMCHAR_LEN' * NARGS bytes on +the stack, i.e. the worst-case number of bytes for NARGS `Emchar's to +fit in the string. + + Then, the loop checks that each element is a character, converting +integers in the process. Like many other functions in XEmacs, this +function silently accepts integers where characters are expected, for +historical and compatibility reasons. Unless you know what you are +doing, `CHECK_CHAR' will also suffice. `XCHAR (lisp_char)' extracts +the `Emchar' from the `Lisp_Object', and `set_charptr_emchar' stores it +to storage, increasing `p' in the process. + + Other instructive examples of correct coding under Mule can be found +all over the XEmacs code. For starters, I recommend +`Fnormalize_menu_item_name' in `menubar.c'. After you have understood +this section of the manual and studied the examples, you can proceed +writing new Mule-aware code. + + +File: internals.info, Node: Techniques for XEmacs Developers, Prev: Coding for Mule, Up: Rules When Writing New C Code + +Techniques for XEmacs Developers +================================ + +To make a purified XEmacs, do: `make puremacs'. To make a quantified +XEmacs, do: `make quantmacs'. + + You simply can't dump Quantified and Purified images (unless using +the portable dumper). Purify gets confused when xemacs frees memory in +one process that was allocated in a _different_ process on a different +machine!. Run it like so: + temacs -batch -l loadup.el run-temacs XEMACS-ARGS... + + Before you go through the trouble, are you compiling with all +debugging and error-checking off? If not, try that first. Be warned +that while Quantify is directly responsible for quite a few +optimizations which have been made to XEmacs, doing a run which +generates results which can be acted upon is not necessarily a trivial +task. + + Also, if you're still willing to do some runs make sure you configure +with the `--quantify' flag. That will keep Quantify from starting to +record data until after the loadup is completed and will shut off +recording right before it shuts down (which generates enough bogus data +to throw most results off). It also enables three additional elisp +commands: `quantify-start-recording-data', +`quantify-stop-recording-data' and `quantify-clear-data'. + + If you want to make XEmacs faster, target your favorite slow +benchmark, run a profiler like Quantify, `gprof', or `tcov', and figure +out where the cycles are going. In many cases you can localize the +problem (because a particular new feature or even a single patch +elicited it). Don't hesitate to use brute force techniques like a +global counter incremented at strategic places, especially in +combination with other performance indications (_e.g._, degree of +buffer fragmentation into extents). + + Specific projects: + + * Make the garbage collector faster. Figure out how to write an + incremental garbage collector. + + * Write a compiler that takes bytecode and spits out C code. + Unfortunately, you will then need a C compiler and a more fully + developed module system. + + * Speed up redisplay. + + * Speed up syntax highlighting. It was suggested that "maybe moving + some of the syntax highlighting capabilities into C would make a + difference." Wrong idea, I think. When processing one large file + a particular low-level routine was being called 40 _million_ times + simply for _one_ call to `newline-and-indent'. Syntax + highlighting needs to be rewritten to use a reliable, fast parser, + then to trust the pre-parsed structure, and only do + re-highlighting locally to a text change. Modern machines are + fast enough to implement such parsers in Lisp; but no machine will + ever be fast enough to deal with quadratic (or worse) algorithms! + + * Implement tail recursion in Emacs Lisp (hard!). + + Unfortunately, Emacs Lisp is slow, and is going to stay slow. +Function calls in elisp are especially expensive. Iterating over a +long list is going to be 30 times faster implemented in C than in Elisp. + + Heavily used small code fragments need to be fast. The traditional +way to implement such code fragments in C is with macros. But macros +in C are known to be broken. + + Macro arguments that are repeatedly evaluated may suffer from +repeated side effects or suboptimal performance. + + Variable names used in macros may collide with caller's variables, +causing (at least) unwanted compiler warnings. + + In order to solve these problems, and maintain statement semantics, +one should use the `do { ... } while (0)' trick while trying to +reference macro arguments exactly once using local variables. + + Let's take a look at this poor macro definition: + + #define MARK_OBJECT(obj) \ + if (!marked_p (obj)) mark_object (obj), did_mark = 1 + + This macro evaluates its argument twice, and also fails if used like +this: + if (flag) MARK_OBJECT (obj); else do_something(); + + A much better definition is + + #define MARK_OBJECT(obj) do { \ + Lisp_Object mo_obj = (obj); \ + if (!marked_p (mo_obj)) \ + { \ + mark_object (mo_obj); \ + did_mark = 1; \ + } \ + } while (0) + + Notice the elimination of double evaluation by using the local +variable with the obscure name. Writing safe and efficient macros +requires great care. The one problem with macros that cannot be +portably worked around is, since a C block has no value, a macro used +as an expression rather than a statement cannot use the techniques just +described to avoid multiple evaluation. + + In most cases where a macro has function semantics, an inline +function is a better implementation technique. Modern compiler +optimizers tend to inline functions even if they have no `inline' +keyword, and configure magic ensures that the `inline' keyword can be +safely used as an additional compiler hint. Inline functions used in a +single .c files are easy. The function must already be defined to be +`static'. Just add another `inline' keyword to the definition. + + inline static int + heavily_used_small_function (int arg) + { + ... + } + + Inline functions in header files are trickier, because we would like +to make the following optimization if the function is _not_ inlined +(for example, because we're compiling for debugging). We would like the +function to be defined externally exactly once, and each calling +translation unit would create an external reference to the function, +instead of including a definition of the inline function in the object +code of every translation unit that uses it. This optimization is +currently only available for gcc. But you don't have to worry about the +trickiness; just define your inline functions in header files using this +pattern: + + INLINE_HEADER int + i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg); + INLINE_HEADER int + i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg) + { + ... + } + + The declaration right before the definition is to prevent warnings +when compiling with `gcc -Wmissing-declarations'. I consider issuing +this warning for inline functions a gcc bug, but the gcc maintainers +disagree. + + Every header which contains inline functions, either directly by +using `INLINE_HEADER' or indirectly by using `DECLARE_LRECORD' must be +added to `inline.c''s includes to make the optimization described above +work. (Optimization note: if all INLINE_HEADER functions are in fact +inlined in all translation units, then the linker can just discard +`inline.o', since it contains only unreferenced code). + + To get started debugging XEmacs, take a look at the `.gdbinit' and +`.dbxrc' files in the `src' directory. See the section in the XEmacs +FAQ on How to Debug an XEmacs problem with a debugger. + + After making source code changes, run `make check' to ensure that +you haven't introduced any regressions. If you want to make xemacs more +reliable, please improve the test suite in `tests/automated'. + + Did you make sure you didn't introduce any new compiler warnings? + + Before submitting a patch, please try compiling at least once with + + configure --with-mule --use-union-type --error-checking=all + + Here are things to know when you create a new source file: + + * All `.c' files should `#include ' first. Almost all + `.c' files should `#include "lisp.h"' second. + + * Generated header files should be included using the `#include + <...>' syntax, not the `#include "..."' syntax. The generated + headers are: + + `config.h sheap-adjust.h paths.h Emacs.ad.h' + + The basic rule is that you should assume builds using `--srcdir' + and the `#include <...>' syntax needs to be used when the + to-be-included generated file is in a potentially different + directory _at compile time_. The non-obvious C rule is that + `#include "..."' means to search for the included file in the same + directory as the including file, _not_ in the current directory. + + * Header files should _not_ include `' and `"lisp.h"'. It + is the responsibility of the `.c' files that use it to do so. + + + Here is a checklist of things to do when creating a new lisp object +type named FOO: + + 1. create FOO.h + + 2. create FOO.c + + 3. add definitions of `syms_of_FOO', etc. to `FOO.c' + + 4. add declarations of `syms_of_FOO', etc. to `symsinit.h' + + 5. add calls to `syms_of_FOO', etc. to `emacs.c' + + 6. add definitions of macros like `CHECK_FOO' and `FOOP' to `FOO.h' + + 7. add the new type index to `enum lrecord_type' + + 8. add a DEFINE_LRECORD_IMPLEMENTATION call to `FOO.c' + + 9. add an INIT_LRECORD_IMPLEMENTATION call to `syms_of_FOO.c' + + +File: internals.info, Node: Regression Testing XEmacs, Next: A Summary of the Various XEmacs Modules, Prev: Rules When Writing New C Code, Up: Top + +Regression Testing XEmacs +************************* + +The source directory `tests/automated' contains XEmacs' automated test +suite. The usual way of running all the tests is running `make check' +from the top-level source directory. + + The test suite is unfinished and it's still lacking some essential +features. It is nevertheless recommended that you run the tests to +confirm that XEmacs behaves correctly. + + If you want to run a specific test case, you can do it from the +command-line like this: + + $ xemacs -batch -l test-harness.elc -f batch-test-emacs TEST-FILE + + If something goes wrong, you can run the test suite interactively by +loading `test-harness.el' into a running XEmacs and typing `M-x +test-emacs-test-file RET RET'. You will see a log of passed +and failed tests, which should allow you to investigate the source of +the error and ultimately fix the bug. + + Adding a new test file is trivial: just create a new file here and it +will be run. There is no need to byte-compile any of the files in this +directory--the test-harness will take care of any necessary +byte-compilation. + + Look at the existing test cases for the examples of coding test +cases. It all boils down to your imagination and judicious use of the +macros `Assert', `Check-Error', `Check-Error-Message', and +`Check-Message'. + + Here's a simple example checking case-sensitive and case-insensitive +comparisons from `case-tests.el'. + + (with-temp-buffer + (insert "Test Buffer") + (let ((case-fold-search t)) + (goto-char (point-min)) + (Assert (eq (search-forward "test buffer" nil t) 12)) + (goto-char (point-min)) + (Assert (eq (search-forward "Test buffer" nil t) 12)) + (goto-char (point-min)) + (Assert (eq (search-forward "Test Buffer" nil t) 12)) + + (setq case-fold-search nil) + (goto-char (point-min)) + (Assert (not (search-forward "test buffer" nil t))) + (goto-char (point-min)) + (Assert (not (search-forward "Test buffer" nil t))) + (goto-char (point-min)) + (Assert (eq (search-forward "Test Buffer" nil t) 12)))) + + This example could be inserted in a file in `tests/automated', and +it would be a complete test, automatically executed when you run `make +check' after building XEmacs. More complex tests may require +substantial temporary scaffolding to create the environment that elicits +the bugs, but the top-level Makefile and `test-harness.el' handle the +running and collection of results from the `Assert', `Check-Error', +`Check-Error-Message', and `Check-Message' macros. + + In general, you should avoid using functionality from packages in +your tests, because you can't be sure that everyone will have the +required package. However, if you've got a test that works, by all +means add it. Simply wrap the test in an appropriate test, add a +notice that the test was skipped, and update the `skipped-test-reasons' +hashtable. Here's an example from `syntax-tests.el': + + ;; Test forward-comment at buffer boundaries + (with-temp-buffer + + ;; try to use exactly what you need: featurep, boundp, fboundp + (if (not (fboundp 'c-mode)) + + ;; We should provide a standard function for this boilerplate, + ;; probably called `Skip-Test' -- check for that API with C-h f + (let* ((reason "c-mode unavailable") + (count (gethash reason skipped-test-reasons))) + (puthash reason (if (null count) 1 (1+ count)) + skipped-test-reasons) + (Print-Skip "comment and parse-partial-sexp tests" reason)) + + ;; and here's the test code + (c-mode) + (insert "// comment\n") + (forward-comment -2) + (Assert (eq (point) (point-min))) + (let ((point (point))) + (insert "/* comment */") + (goto-char point) + (forward-comment 2) + (Assert (eq (point) (point-max))) + (parse-partial-sexp point (point-max))))) + + `Skip-Test' is intended for use with features that are normally +present in typical configurations. For truly optional features, or +tests that apply to one of several alternative implementations (eg, to +GTK widgets, but not Athena, Motif, MS Windows, or Carbon), simply +silently omit the test. + + +File: internals.info, Node: A Summary of the Various XEmacs Modules, Next: Allocation of Objects in XEmacs Lisp, Prev: Regression Testing XEmacs, Up: Top + +A Summary of the Various XEmacs Modules +*************************************** + +This is accurate as of XEmacs 20.0. + +* Menu: + +* Low-Level Modules:: +* Basic Lisp Modules:: +* Modules for Standard Editing Operations:: +* Editor-Level Control Flow Modules:: +* Modules for the Basic Displayable Lisp Objects:: +* Modules for other Display-Related Lisp Objects:: +* Modules for the Redisplay Mechanism:: +* Modules for Interfacing with the File System:: +* Modules for Other Aspects of the Lisp Interpreter and Object System:: +* Modules for Interfacing with the Operating System:: +* Modules for Interfacing with X Windows:: +* Modules for Internationalization:: +* Modules for Regression Testing:: + + +File: internals.info, Node: Low-Level Modules, Next: Basic Lisp Modules, Up: A Summary of the Various XEmacs Modules + +Low-Level Modules +================= + + config.h + + This is automatically generated from `config.h.in' based on the +results of configure tests and user-selected optional features and +contains preprocessor definitions specifying the nature of the +environment in which XEmacs is being compiled. + + paths.h + + This is automatically generated from `paths.h.in' based on supplied +configure values, and allows for non-standard installed configurations +of the XEmacs directories. It's currently broken, though. + + emacs.c + signal.c + + `emacs.c' contains `main()' and other code that performs the most +basic environment initializations and handles shutting down the XEmacs +process (this includes `kill-emacs', the normal way that XEmacs is +exited; `dump-emacs', which is used during the build process to write +out the XEmacs executable; `run-emacs-from-temacs', which can be used +to start XEmacs directly when temacs has finished loading all the Lisp +code; and emergency code to handle crashes [XEmacs tries to auto-save +all files before it crashes]). + + Low-level code that directly interacts with the Unix signal +mechanism, however, is in `signal.c'. Note that this code does not +handle system dependencies in interfacing to signals; that is handled +using the `syssignal.h' header file, described in section J below. + + unexaix.c + unexalpha.c + unexapollo.c + unexconvex.c + unexec.c + unexelf.c + unexelfsgi.c + unexencap.c + unexenix.c + unexfreebsd.c + unexfx2800.c + unexhp9k3.c + unexhp9k800.c + unexmips.c + unexnext.c + unexsol2.c + unexsunos4.c + + These modules contain code dumping out the XEmacs executable on +various different systems. (This process is highly machine-specific and +requires intimate knowledge of the executable format and the memory map +of the process.) Only one of these modules is actually used; this is +chosen by `configure'. + + ecrt0.c + lastfile.c + pre-crt0.c + + These modules are used in conjunction with the dump mechanism. On +some systems, an alternative version of the C startup code (the actual +code that receives control from the operating system when the process is +started, and which calls `main()') is required so that the dumping +process works properly; `crt0.c' provides this. + + `pre-crt0.c' and `lastfile.c' should be the very first and very last +file linked, respectively. (Actually, this is not really true. +`lastfile.c' should be after all Emacs modules whose initialized data +should be made constant, and before all other Emacs files and all +libraries. In particular, the allocation modules `gmalloc.c', +`alloca.c', etc. are normally placed past `lastfile.c', and all of the +files that implement Xt widget classes _must_ be placed after +`lastfile.c' because they contain various structures that must be +statically initialized and into which Xt writes at various times.) +`pre-crt0.c' and `lastfile.c' contain exported symbols that are used to +determine the start and end of XEmacs' initialized data space when +dumping. + + alloca.c + free-hook.c + getpagesize.h + gmalloc.c + malloc.c + mem-limits.h + ralloc.c + vm-limit.c + + These handle basic C allocation of memory. `alloca.c' is an +emulation of the stack allocation function `alloca()' on machines that +lack this. (XEmacs makes extensive use of `alloca()' in its code.) + + `gmalloc.c' and `malloc.c' are two implementations of the standard C +functions `malloc()', `realloc()' and `free()'. They are often used in +place of the standard system-provided `malloc()' because they usually +provide a much faster implementation, at the expense of additional +memory use. `gmalloc.c' is a newer implementation that is much more +memory-efficient for large allocations than `malloc.c', and should +always be preferred if it works. (At one point, `gmalloc.c' didn't work +on some systems where `malloc.c' worked; but this should be fixed now.) + + `ralloc.c' is the "relocating allocator". It provides functions +similar to `malloc()', `realloc()' and `free()' that allocate memory +that can be dynamically relocated in memory. The advantage of this is +that allocated memory can be shuffled around to place all the free +memory at the end of the heap, and the heap can then be shrunk, +releasing the memory back to the operating system. The use of this can +be controlled with the configure option `--rel-alloc'; if enabled, +memory allocated for buffers will be relocatable, so that if a very +large file is visited and the buffer is later killed, the memory can be +released to the operating system. (The disadvantage of this mechanism +is that it can be very slow. On systems with the `mmap()' system call, +the XEmacs version of `ralloc.c' uses this to move memory around +without actually having to block-copy it, which can speed things up; +but it can still cause noticeable performance degradation.) + + `free-hook.c' contains some debugging functions for checking for +invalid arguments to `free()'. + + `vm-limit.c' contains some functions that warn the user when memory +is getting low. These are callback functions that are called by +`gmalloc.c' and `malloc.c' at appropriate times. + + `getpagesize.h' provides a uniform interface for retrieving the size +of a page in virtual memory. `mem-limits.h' provides a uniform +interface for retrieving the total amount of available virtual memory. +Both are similar in spirit to the `sys*.h' files described in section +J, below. + + blocktype.c + blocktype.h + dynarr.c + + These implement a couple of basic C data types to facilitate memory +allocation. The `Blocktype' type efficiently manages the allocation of +fixed-size blocks by minimizing the number of times that `malloc()' and +`free()' are called. It allocates memory in large chunks, subdivides +the chunks into blocks of the proper size, and returns the blocks as +requested. When blocks are freed, they are placed onto a linked list, +so they can be efficiently reused. This data type is not much used in +XEmacs currently, because it's a fairly new addition. + + The `Dynarr' type implements a "dynamic array", which is similar to +a standard C array but has no fixed limit on the number of elements it +can contain. Dynamic arrays can hold elements of any type, and when +you add a new element, the array automatically resizes itself if it +isn't big enough. Dynarrs are extensively used in the redisplay +mechanism. + + inline.c + + This module is used in connection with inline functions (available in +some compilers). Often, inline functions need to have a corresponding +non-inline function that does the same thing. This module is where they +reside. It contains no actual code, but defines some special flags that +cause inline functions defined in header files to be rendered as actual +functions. It then includes all header files that contain any inline +function definitions, so that each one gets a real function equivalent. + + debug.c + debug.h + + These functions provide a system for doing internal consistency +checks during code development. This system is not currently used; +instead the simpler `assert()' macro is used along with the various +checks provided by the `--error-check-*' configuration options. + + universe.h + + This is not currently used. + + +File: internals.info, Node: Basic Lisp Modules, Next: Modules for Standard Editing Operations, Prev: Low-Level Modules, Up: A Summary of the Various XEmacs Modules + +Basic Lisp Modules +================== + + lisp-disunion.h + lisp-union.h + lisp.h + lrecord.h + symsinit.h + + These are the basic header files for all XEmacs modules. Each module +includes `lisp.h', which brings the other header files in. `lisp.h' +contains the definitions of the structures and extractor and +constructor macros for the basic Lisp objects and various other basic +definitions for the Lisp environment, as well as some general-purpose +definitions (e.g. `min()' and `max()'). `lisp.h' includes either +`lisp-disunion.h' or `lisp-union.h', depending on whether +`USE_UNION_TYPE' is defined. These files define the typedef of the +Lisp object itself (as described above) and the low-level macros that +hide the actual implementation of the Lisp object. All extractor and +constructor macros for particular types of Lisp objects are defined in +terms of these low-level macros. + + As a general rule, all typedefs should go into the typedefs section +of `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 be placed into other header files. Forward structure +declarations (i.e. a simple declaration like `struct foo;' where the +structure itself is defined elsewhere) should be placed into the +typedefs section as necessary. + + `lrecord.h' contains the basic structures and macros that implement +all record-type Lisp objects--i.e. all objects whose type is a field in +their C structure, which includes all objects except the few most basic +ones. + + `lisp.h' contains prototypes for most of the exported functions in +the various modules. Lisp primitives defined using `DEFUN' that need +to be called by C code should be declared using `EXFUN'. Other +function prototypes should be placed either into the appropriate +section of `lisp.h', or into a module-specific header file, depending +on how general-purpose the function is and whether it has +special-purpose argument types requiring definitions not in `lisp.h'.) +All initialization functions are prototyped in `symsinit.h'. + + alloc.c + + The large module `alloc.c' implements all of the basic allocation and +garbage collection for Lisp objects. The most commonly used Lisp +objects are allocated in chunks, similar to the Blocktype data type +described above; others are allocated in individually `malloc()'ed +blocks. This module provides the foundation on which all other aspects +of the Lisp environment sit, and is the first module initialized at +startup. + + Note that `alloc.c' provides a series of generic functions that are +not dependent on any particular object type, and interfaces to +particular types of objects using a standardized interface of +type-specific methods. This scheme is a fundamental principle of +object-oriented programming and is heavily used throughout XEmacs. The +great advantage of this is that it allows for a clean separation of +functionality into different modules--new classes of Lisp objects, new +event interfaces, new device types, new stream interfaces, etc. can be +added transparently without affecting code anywhere else in XEmacs. +Because the different subsystems are divided into general and specific +code, adding a new subtype within a subsystem will in general not +require changes to the generic subsystem code or affect any of the other +subtypes in the subsystem; this provides a great deal of robustness to +the XEmacs code. + + eval.c + backtrace.h + + This module contains all of the functions to handle the flow of +control. This includes the mechanisms of defining functions, calling +functions, traversing stack frames, and binding variables; the control +primitives and other special forms such as `while', `if', `eval', +`let', `and', `or', `progn', etc.; handling of non-local exits, +unwind-protects, and exception handlers; entering the debugger; methods +for the subr Lisp object type; etc. It does _not_ include the `read' +function, the `print' function, or the handling of symbols and obarrays. + + `backtrace.h' contains some structures related to stack frames and +the flow of control. + + lread.c + + This module implements the Lisp reader and the `read' function, +which converts text into Lisp objects, according to the read syntax of +the objects, as described above. This is similar to the parser that is +a part of all compilers. + + print.c + + This module implements the Lisp print mechanism and the `print' +function and related functions. This is the inverse of the Lisp reader +- it converts Lisp objects to a printed, textual representation. +(Hopefully something that can be read back in using `read' to get an +equivalent object.) + + general.c + symbols.c + symeval.h + + `symbols.c' implements the handling of symbols, obarrays, and +retrieving the values of symbols. Much of the code is devoted to +handling the special "symbol-value-magic" objects that define special +types of variables--this includes buffer-local variables, variable +aliases, variables that forward into C variables, etc. This module is +initialized extremely early (right after `alloc.c'), because it is here +that the basic symbols `t' and `nil' are created, and those symbols are +used everywhere throughout XEmacs. + + `symeval.h' contains the definitions of symbol structures and the +`DEFVAR_LISP()' and related macros for declaring variables. + + data.c + floatfns.c + fns.c + + These modules implement the methods and standard Lisp primitives for +all the basic Lisp object types other than symbols (which are described +above). `data.c' contains all the predicates (primitives that return +whether an object is of a particular type); the integer arithmetic +functions; and the basic accessor and mutator primitives for the various +object types. `fns.c' contains all the standard predicates for working +with sequences (where, abstractly speaking, a sequence is an ordered set +of objects, and can be represented by a list, string, vector, or +bit-vector); it also contains `equal', perhaps on the grounds that bulk +of the operation of `equal' is comparing sequences. `floatfns.c' +contains methods and primitives for floats and floating-point +arithmetic. + + bytecode.c + bytecode.h + + `bytecode.c' implements the byte-code interpreter and +compiled-function objects, and `bytecode.h' contains associated +structures. Note that the byte-code _compiler_ is written in Lisp. + + +File: internals.info, Node: Modules for Standard Editing Operations, Next: Editor-Level Control Flow Modules, Prev: Basic Lisp Modules, Up: A Summary of the Various XEmacs Modules + +Modules for Standard Editing Operations +======================================= + + buffer.c + buffer.h + bufslots.h + + `buffer.c' implements the "buffer" Lisp object type. This includes +functions that create and destroy buffers; retrieve buffers by name or +by other properties; manipulate lists of buffers (remember that buffers +are permanent objects and stored in various ordered lists); retrieve or +change buffer properties; etc. It also contains the definitions of all +the built-in buffer-local variables (which can be viewed as buffer +properties). It does _not_ contain code to manipulate buffer-local +variables (that's in `symbols.c', described above); or code to +manipulate the text in a buffer. + + `buffer.h' defines the structures associated with a buffer and the +various macros for retrieving text from a buffer and special buffer +positions (e.g. `point', the default location for text insertion). It +also contains macros for working with buffer positions and converting +between their representations as character offsets and as byte offsets +(under MULE, they are different, because characters can be multi-byte). +It is one of the largest header files. + + `bufslots.h' defines the fields in the buffer structure that +correspond to the built-in buffer-local variables. It is its own +header file because it is included many times in `buffer.c', as a way +of iterating over all the built-in buffer-local variables. + + insdel.c + insdel.h + + `insdel.c' contains low-level functions for inserting and deleting +text in a buffer, keeping track of changed regions for use by +redisplay, and calling any before-change and after-change functions +that may have been registered for the buffer. It also contains the +actual functions that convert between byte offsets and character +offsets. + + `insdel.h' contains associated headers. + + marker.c + + This module implements the "marker" Lisp object type, which +conceptually is a pointer to a text position in a buffer that moves +around as text is inserted and deleted, so as to remain in the same +relative position. This module doesn't actually move the markers around +- that's handled in `insdel.c'. This module just creates them and +implements the primitives for working with them. As markers are simple +objects, this does not entail much. + + Note that the standard arithmetic primitives (e.g. `+') accept +markers in place of integers and automatically substitute the value of +`marker-position' for the marker, i.e. an integer describing the +current buffer position of the marker. + + extents.c + extents.h + + This module implements the "extent" Lisp object type, which is like +a marker that works over a range of text rather than a single position. +Extents are also much more complex and powerful than markers and have a +more efficient (and more algorithmically complex) implementation. The +implementation is described in detail in comments in `extents.c'. + + The code in `extents.c' works closely with `insdel.c' so that +extents are properly moved around as text is inserted and deleted. +There is also code in `extents.c' that provides information needed by +the redisplay mechanism for efficient operation. (Remember that extents +can have display properties that affect [sometimes drastically, as in +the `invisible' property] the display of the text they cover.) + + editfns.c + + `editfns.c' contains the standard Lisp primitives for working with a +buffer's text, and calls the low-level functions in `insdel.c'. It +also contains primitives for working with `point' (the default buffer +insertion location). + + `editfns.c' also contains functions for retrieving various +characteristics from the external environment: the current time, the +process ID of the running XEmacs process, the name of the user who ran +this XEmacs process, etc. It's not clear why this code is in +`editfns.c'. + + callint.c + cmds.c + commands.h + + These modules implement the basic "interactive" commands, i.e. +user-callable functions. Commands, as opposed to other functions, have +special ways of getting their parameters interactively (by querying the +user), as opposed to having them passed in a normal function +invocation. Many commands are not really meant to be called from other +Lisp functions, because they modify global state in a way that's often +undesired as part of other Lisp functions. + + `callint.c' implements the mechanism for querying the user for +parameters and calling interactive commands. The bulk of this module is +code that parses the interactive spec that is supplied with an +interactive command. + + `cmds.c' implements the basic, most commonly used editing commands: +commands to move around the current buffer and insert and delete +characters. These commands are implemented using the Lisp primitives +defined in `editfns.c'. + + `commands.h' contains associated structure definitions and +prototypes. + + regex.c + regex.h + search.c + + `search.c' implements the Lisp primitives for searching for text in +a buffer, and some of the low-level algorithms for doing this. In +particular, the fast fixed-string Boyer-Moore search algorithm is +implemented in `search.c'. The low-level algorithms for doing +regular-expression searching, however, are implemented in `regex.c' and +`regex.h'. These two modules are largely independent of XEmacs, and +are similar to (and based upon) the regular-expression routines used in +`grep' and other GNU utilities. + + doprnt.c + + `doprnt.c' implements formatted-string processing, similar to +`printf()' command in C. + + undo.c + + This module implements the undo mechanism for tracking buffer +changes. Most of this could be implemented in Lisp. + + +File: internals.info, Node: Editor-Level Control Flow Modules, Next: Modules for the Basic Displayable Lisp Objects, Prev: Modules for Standard Editing Operations, Up: A Summary of the Various XEmacs Modules + +Editor-Level Control Flow Modules +================================= + + event-Xt.c + event-msw.c + event-stream.c + event-tty.c + events-mod.h + gpmevent.c + gpmevent.h + events.c + events.h + + These implement the handling of events (user input and other system +notifications). + + `events.c' and `events.h' define the "event" Lisp object type and +primitives for manipulating it. + + `event-stream.c' implements the basic functions for working with +event queues, dispatching an event by looking it up in relevant keymaps +and such, and handling timeouts; this includes the primitives +`next-event' and `dispatch-event', as well as related primitives such +as `sit-for', `sleep-for', and `accept-process-output'. +(`event-stream.c' is one of the hairiest and trickiest modules in +XEmacs. Beware! You can easily mess things up here.) + + `event-Xt.c' and `event-tty.c' implement the low-level interfaces +onto retrieving events from Xt (the X toolkit) and from TTY's (using +`read()' and `select()'), respectively. The event interface enforces a +clean separation between the specific code for interfacing with the +operating system and the generic code for working with events, by +defining an API of basic, low-level event methods; `event-Xt.c' and +`event-tty.c' are two different implementations of this API. To add +support for a new operating system (e.g. NeXTstep), one merely needs to +provide another implementation of those API functions. + + Note that the choice of whether to use `event-Xt.c' or `event-tty.c' +is made at compile time! Or at the very latest, it is made at startup +time. `event-Xt.c' handles events for _both_ X and TTY frames; +`event-tty.c' is only used when X support is not compiled into XEmacs. +The reason for this is that there is only one event loop in XEmacs: +thus, it needs to be able to receive events from all different kinds of +frames. + + keymap.c + keymap.h + + `keymap.c' and `keymap.h' define the "keymap" Lisp object type and +associated methods and primitives. (Remember that keymaps are objects +that associate event descriptions with functions to be called to +"execute" those events; `dispatch-event' looks up events in the +relevant keymaps.) + + cmdloop.c + + `cmdloop.c' contains functions that implement the actual editor +command loop--i.e. the event loop that cyclically retrieves and +dispatches events. This code is also rather tricky, just like +`event-stream.c'. + + macros.c + macros.h + + These two modules contain the basic code for defining keyboard +macros. These functions don't actually do much; most of the code that +handles keyboard macros is mixed in with the event-handling code in +`event-stream.c'. + + minibuf.c + + This contains some miscellaneous code related to the minibuffer +(most of the minibuffer code was moved into Lisp by Richard Mlynarik). +This includes the primitives for completion (although filename +completion is in `dired.c'), the lowest-level interface to the +minibuffer (if the command loop were cleaned up, this too could be in +Lisp), and code for dealing with the echo area (this, too, was mostly +moved into Lisp, and the only code remaining is code to call out to +Lisp or provide simple bootstrapping implementations early in temacs, +before the echo-area Lisp code is loaded). + + +File: internals.info, Node: Modules for the Basic Displayable Lisp Objects, Next: Modules for other Display-Related Lisp Objects, Prev: Editor-Level Control Flow Modules, Up: A Summary of the Various XEmacs Modules + +Modules for the Basic Displayable Lisp Objects +============================================== + + console-msw.c + console-msw.h + console-stream.c + console-stream.h + console-tty.c + console-tty.h + console-x.c + console-x.h + console.c + console.h + + These modules implement the "console" Lisp object type. A console +contains multiple display devices, but only one keyboard and mouse. +Most of the time, a console will contain exactly one device. + + Consoles are the top of a lisp object inclusion hierarchy. Consoles +contain devices, which contain frames, which contain windows. + + device-msw.c + device-tty.c + device-x.c + device.c + device.h + + These modules implement the "device" Lisp object type. This +abstracts a particular screen or connection on which frames are +displayed. As with Lisp objects, event interfaces, and other +subsystems, the device code is separated into a generic component that +contains a standardized interface (in the form of a set of methods) onto +particular device types. + + The device subsystem defines all the methods and provides method +services for not only device operations but also for the frame, window, +menubar, scrollbar, toolbar, and other displayable-object subsystems. +The reason for this is that all of these subsystems have the same +subtypes (X, TTY, NeXTstep, Microsoft Windows, etc.) as devices do. + + frame-msw.c + frame-tty.c + frame-x.c + frame.c + frame.h + + Each device contains one or more frames in which objects (e.g. text) +are displayed. A frame corresponds to a window in the window system; +usually this is a top-level window but it could potentially be one of a +number of overlapping child windows within a top-level window, using the +MDI (Multiple Document Interface) protocol in Microsoft Windows or a +similar scheme. + + The `frame-*' files implement the "frame" Lisp object type and +provide the generic and device-type-specific operations on frames (e.g. +raising, lowering, resizing, moving, etc.). + + window.c + window.h + + Each frame consists of one or more non-overlapping "windows" (better +known as "panes" in standard window-system terminology) in which a +buffer's text can be displayed. Windows can also have scrollbars +displayed around their edges. + + `window.c' and `window.h' implement the "window" Lisp object type +and provide code to manage windows. Since windows have no associated +resources in the window system (the window system knows only about the +frame; no child windows or anything are used for XEmacs windows), there +is no device-type-specific code here; all of that code is part of the +redisplay mechanism or the code for particular object types such as +scrollbars. + + +File: internals.info, Node: Modules for other Display-Related Lisp Objects, Next: Modules for the Redisplay Mechanism, Prev: Modules for the Basic Displayable Lisp Objects, Up: A Summary of the Various XEmacs Modules + +Modules for other Display-Related Lisp Objects +============================================== + + faces.c + faces.h + + bitmaps.h + glyphs-eimage.c + glyphs-msw.c + glyphs-msw.h + glyphs-widget.c + glyphs-x.c + glyphs-x.h + glyphs.c + glyphs.h + + objects-msw.c + objects-msw.h + objects-tty.c + objects-tty.h + objects-x.c + objects-x.h + objects.c + objects.h + + menubar-msw.c + menubar-msw.h + menubar-x.c + menubar.c + menubar.h + + scrollbar-msw.c + scrollbar-msw.h + scrollbar-x.c + scrollbar-x.h + scrollbar.c + scrollbar.h + + toolbar-msw.c + toolbar-x.c + toolbar.c + toolbar.h + + font-lock.c + + This file provides C support for syntax highlighting--i.e. +highlighting different syntactic constructs of a source file in +different colors, for easy reading. The C support is provided so that +this is fast. + + As of 21.4.10, bugs introduced at the very end of the 21.2 series in +the "syntax properties" code were fixed, and highlighting is acceptably +quick again. However, presumably more improvements are possible, and +the places to look are probably here, in the defun-traversing code, and +in `syntax.c', in the comment-traversing code. + + dgif_lib.c + gif_err.c + gif_lib.h + gifalloc.c + + These modules decode GIF-format image files, for use with glyphs. +These files were removed due to Unisys patent infringement concerns. + + +File: internals.info, Node: Modules for the Redisplay Mechanism, Next: Modules for Interfacing with the File System, Prev: Modules for other Display-Related Lisp Objects, Up: A Summary of the Various XEmacs Modules + +Modules for the Redisplay Mechanism +=================================== + + redisplay-output.c + redisplay-msw.c + redisplay-tty.c + redisplay-x.c + redisplay.c + redisplay.h + + These files provide the redisplay mechanism. As with many other +subsystems in XEmacs, there is a clean separation between the general +and device-specific support. + + `redisplay.c' contains the bulk of the redisplay engine. These +functions update the redisplay structures (which describe how the screen +is to appear) to reflect any changes made to the state of any +displayable objects (buffer, frame, window, etc.) since the last time +that redisplay was called. These functions are highly optimized to +avoid doing more work than necessary (since redisplay is called +extremely often and is potentially a huge time sink), and depend heavily +on notifications from the objects themselves that changes have occurred, +so that redisplay doesn't explicitly have to check each possible object. +The redisplay mechanism also contains a great deal of caching to further +speed things up; some of this caching is contained within the various +displayable objects. + + `redisplay-output.c' goes through the redisplay structures and +converts them into calls to device-specific methods to actually output +the screen changes. + + `redisplay-x.c' and `redisplay-tty.c' are two implementations of +these redisplay output methods, for X frames and TTY frames, +respectively. + + indent.c + + This module contains various functions and Lisp primitives for +converting between buffer positions and screen positions. These +functions call the redisplay mechanism to do most of the work, and then +examine the redisplay structures to get the necessary information. This +module needs work. + + termcap.c + terminfo.c + tparam.c + + These files contain functions for working with the termcap +(BSD-style) and terminfo (System V style) databases of terminal +capabilities and escape sequences, used when XEmacs is displaying in a +TTY. + + cm.c + cm.h + + These files provide some miscellaneous TTY-output functions and +should probably be merged into `redisplay-tty.c'. + + +File: internals.info, Node: Modules for Interfacing with the File System, Next: Modules for Other Aspects of the Lisp Interpreter and Object System, Prev: Modules for the Redisplay Mechanism, Up: A Summary of the Various XEmacs Modules + +Modules for Interfacing with the File System +============================================ + + lstream.c + lstream.h + + These modules implement the "stream" Lisp object type. This is an +internal-only Lisp object that implements a generic buffering stream. +The idea is to provide a uniform interface onto all sources and sinks of +data, including file descriptors, stdio streams, chunks of memory, Lisp +buffers, Lisp strings, etc. That way, I/O functions can be written to +the stream interface and can transparently handle all possible sources +and sinks. (For example, the `read' function can read data from a +file, a string, a buffer, or even a function that is called repeatedly +to return data, without worrying about where the data is coming from or +what-size chunks it is returned in.) + + Note that in the C code, streams are called "lstreams" (for "Lisp +streams") to distinguish them from other kinds of streams, e.g. stdio +streams and C++ I/O streams. + + Similar to other subsystems in XEmacs, lstreams are separated into +generic functions and a set of methods for the different types of +lstreams. `lstream.c' provides implementations of many different types +of streams; others are provided, e.g., in `file-coding.c'. + + fileio.c + + This implements the basic primitives for interfacing with the file +system. This includes primitives for reading files into buffers, +writing buffers into files, checking for the presence or accessibility +of files, canonicalizing file names, etc. Note that these primitives +are usually not invoked directly by the user: There is a great deal of +higher-level Lisp code that implements the user commands such as +`find-file' and `save-buffer'. This is similar to the distinction +between the lower-level primitives in `editfns.c' and the higher-level +user commands in `commands.c' and `simple.el'. + + filelock.c + + This file provides functions for detecting clashes between different +processes (e.g. XEmacs and some external process, or two different +XEmacs processes) modifying the same file. (XEmacs can optionally use +the `lock/' subdirectory to provide a form of "locking" between +different XEmacs processes.) This module is also used by the low-level +functions in `insdel.c' to ensure that, if the first modification is +being made to a buffer whose corresponding file has been externally +modified, the user is made aware of this so that the buffer can be +synched up with the external changes if necessary. + + filemode.c + + This file provides some miscellaneous functions that construct a +`rwxr-xr-x'-type permissions string (as might appear in an `ls'-style +directory listing) given the information returned by the `stat()' +system call. + + dired.c + ndir.h + + These files implement the XEmacs interface to directory searching. +This includes a number of primitives for determining the files in a +directory and for doing filename completion. (Remember that generic +completion is handled by a different mechanism, in `minibuf.c'.) + + `ndir.h' is a header file used for the directory-searching emulation +functions provided in `sysdep.c' (see section J below), for systems +that don't provide any directory-searching functions. (On those +systems, directories can be read directly as files, and parsed.) + + realpath.c + + This file provides an implementation of the `realpath()' function +for expanding symbolic links, on systems that don't implement it or have +a broken implementation. + + +File: internals.info, Node: Modules for Other Aspects of the Lisp Interpreter and Object System, Next: Modules for Interfacing with the Operating System, Prev: Modules for Interfacing with the File System, Up: A Summary of the Various XEmacs Modules + +Modules for Other Aspects of the Lisp Interpreter and Object System +=================================================================== + + elhash.c + elhash.h + hash.c + hash.h + + These files provide two implementations of hash tables. Files +`hash.c' and `hash.h' provide a generic C implementation of hash tables +which can stand independently of XEmacs. Files `elhash.c' and +`elhash.h' provide a separate implementation of hash tables that can +store only Lisp objects, and knows about Lispy things like garbage +collection, and implement the "hash-table" Lisp object type. + + specifier.c + specifier.h + + This module implements the "specifier" Lisp object type. This is +primarily used for displayable properties, and allows for values that +are specific to a particular buffer, window, frame, device, or device +class, as well as a default value existing. This is used, for example, +to control the height of the horizontal scrollbar or the appearance of +the `default', `bold', or other faces. The specifier object consists +of a number of specifications, each of which maps from a buffer, +window, etc. to a value. The function `specifier-instance' looks up a +value given a window (from which a buffer, frame, and device can be +derived). + + chartab.c + chartab.h + casetab.c + + `chartab.c' and `chartab.h' implement the "char table" Lisp object +type, which maps from characters or certain sorts of character ranges +to Lisp objects. The implementation of this object type is optimized +for the internal representation of characters. Char tables come in +different types, which affect the allowed object types to which a +character can be mapped and also dictate certain other properties of +the char table. + + `casetab.c' implements one sort of char table, the "case table", +which maps characters to other characters of possibly different case. +These are used by XEmacs to implement case-changing primitives and to +do case-insensitive searching. + + syntax.c + syntax.h + + This module implements "syntax tables", another sort of char table +that maps characters into syntax classes that define the syntax of these +characters (e.g. a parenthesis belongs to a class of `open' characters +that have corresponding `close' characters and can be nested). This +module also implements the Lisp "scanner", a set of primitives for +scanning over text based on syntax tables. This is used, for example, +to find the matching parenthesis in a command such as `forward-sexp', +and by `font-lock.c' to locate quoted strings, comments, etc. + + Syntax codes are implemented as bitfields in an int. Bits 0-6 +contain the syntax code itself, bit 7 is a special prefix flag used for +Lisp, and bits 16-23 contain comment syntax flags. From the Lisp +programmer's point of view, there are 11 flags: 2 styles X 2 characters +X {start, end} flags for two-character comment delimiters, 2 style +flags for one-character comment delimiters, and the prefix flag. + + Internally, however, the characters used in multi-character +delimiters will have non-comment-character syntax classes (_e.g._, the +`/' in C's `/*' comment-start delimiter has "punctuation" (here meaning +"operator-like") class in C modes). Thus in a mixed comment style, +such as C++'s `//' to end of line, is represented by giving `/' the +"punctuation" class and the "style b first character of start sequence" +and "style b second character of start sequence" flags. The fact that +class is _not_ punctuation allows the syntax scanner to recognize that +this is a multi-character delimiter. The `newline' character is given +(single-character) "comment-end" _class_ and the "style b first +character of end sequence" _flag_. The "comment-end" class allows the +scanner to determine that no second character is needed to terminate +the comment. + + casefiddle.c + + This module implements various Lisp primitives for upcasing, +downcasing and capitalizing strings or regions of buffers. + + rangetab.c + + This module implements the "range table" Lisp object type, which +provides for a mapping from ranges of integers to arbitrary Lisp +objects. + + opaque.c + opaque.h + + This module implements the "opaque" Lisp object type, an +internal-only Lisp object that encapsulates an arbitrary block of memory +so that it can be managed by the Lisp allocation system. To create an +opaque object, you call `make_opaque()', passing a pointer to a block +of memory. An object is created that is big enough to hold the memory, +which is copied into the object's storage. The object will then stick +around as long as you keep pointers to it, after which it will be +automatically reclaimed. + + Opaque objects can also have an arbitrary "mark method" associated +with them, in case the block of memory contains other Lisp objects that +need to be marked for garbage-collection purposes. (If you need other +object methods, such as a finalize method, you should just go ahead and +create a new Lisp object type--it's not hard.) + + abbrev.c + + This function provides a few primitives for doing dynamic +abbreviation expansion. In XEmacs, most of the code for this has been +moved into Lisp. Some C code remains for speed and because the +primitive `self-insert-command' (which is executed for all +self-inserting characters) hooks into the abbrev mechanism. +(`self-insert-command' is itself in C only for speed.) + + doc.c + + This function provides primitives for retrieving the documentation +strings of functions and variables. These documentation strings contain +certain special markers that get dynamically expanded (e.g. a +reverse-lookup is performed on some named functions to retrieve their +current key bindings). Some documentation strings (in particular, for +the built-in primitives and pre-loaded Lisp functions) are stored +externally in a file `DOC' in the `lib-src/' directory and need to be +fetched from that file. (Part of the build stage involves building this +file, and another part involves constructing an index for this file and +embedding it into the executable, so that the functions in `doc.c' do +not have to search the entire `DOC' file to find the appropriate +documentation string.) + + md5.c + + This function provides a Lisp primitive that implements the MD5 +secure hashing scheme, used to create a large hash value of a string of +data such that the data cannot be derived from the hash value. This is +used for various security applications on the Internet. + + +File: internals.info, Node: Modules for Interfacing with the Operating System, Next: Modules for Interfacing with X Windows, Prev: Modules for Other Aspects of the Lisp Interpreter and Object System, Up: A Summary of the Various XEmacs Modules + +Modules for Interfacing with the Operating System +================================================= + + callproc.c + process.c + process.h + + These modules allow XEmacs to spawn and communicate with subprocesses +and network connections. + + `callproc.c' implements (through the `call-process' primitive) what +are called "synchronous subprocesses". This means that XEmacs runs a +program, waits till it's done, and retrieves its output. A typical +example might be calling the `ls' program to get a directory listing. + + `process.c' and `process.h' implement "asynchronous subprocesses". +This means that XEmacs starts a program and then continues normally, +not waiting for the process to finish. Data can be sent to the process +or retrieved from it as it's running. This is used for the `shell' +command (which provides a front end onto a shell program such as +`csh'), the mail and news readers implemented in XEmacs, etc. The +result of calling `start-process' to start a subprocess is a process +object, a particular kind of object used to communicate with the +subprocess. You can send data to the process by passing the process +object and the data to `send-process', and you can specify what happens +to data retrieved from the process by setting properties of the process +object. (When the process sends data, XEmacs receives a process event, +which says that there is data ready. When `dispatch-event' is called +on this event, it reads the data from the process and does something +with it, as specified by the process object's properties. Typically, +this means inserting the data into a buffer or calling a function.) +Another property of the process object is called the "sentinel", which +is a function that is called when the process terminates. + + Process objects are also used for network connections (connections +to a process running on another machine). Network connections are +started with `open-network-stream' but otherwise work just like +subprocesses. + + sysdep.c + sysdep.h + + These modules implement most of the low-level, messy operating-system +interface code. This includes various device control (ioctl) operations +for file descriptors, TTY's, pseudo-terminals, etc. (usually this stuff +is fairly system-dependent; thus the name of this module), and emulation +of standard library functions and system calls on systems that don't +provide them or have broken versions. + + sysdir.h + sysfile.h + sysfloat.h + sysproc.h + syspwd.h + syssignal.h + systime.h + systty.h + syswait.h + + These header files provide consistent interfaces onto +system-dependent header files and system calls. The idea is that, +instead of including a standard header file like `' (which +may or may not exist on various systems) or having to worry about +whether all system provide a particular preprocessor constant, or +having to deal with the four different paradigms for manipulating +signals, you just include the appropriate `sys*.h' header file, which +includes all the right system header files, defines and missing +preprocessor constants, provides a uniform interface onto system calls, +etc. + + `sysdir.h' provides a uniform interface onto directory-querying +functions. (In some cases, this is in conjunction with emulation +functions in `sysdep.c'.) + + `sysfile.h' includes all the necessary header files for standard +system calls (e.g. `read()'), ensures that all necessary `open()' and +`stat()' preprocessor constants are defined, and possibly (usually) +substitutes sugared versions of `read()', `write()', etc. that +automatically restart interrupted I/O operations. + + `sysfloat.h' includes the necessary header files for floating-point +operations. + + `sysproc.h' includes the necessary header files for calling +`select()', `fork()', `execve()', socket operations, and the like, and +ensures that the `FD_*()' macros for descriptor-set manipulations are +available. + + `syspwd.h' includes the necessary header files for obtaining +information from `/etc/passwd' (the functions are emulated under VMS). + + `syssignal.h' includes the necessary header files for +signal-handling and provides a uniform interface onto the different +signal-handling and signal-blocking paradigms. + + `systime.h' includes the necessary header files and provides uniform +interfaces for retrieving the time of day, setting file +access/modification times, getting the amount of time used by the XEmacs +process, etc. + + `systty.h' buffers against the infinitude of different ways of +controlling TTY's. + + `syswait.h' provides a uniform way of retrieving the exit status +from a `wait()'ed-on process (some systems use a union, others use an +int). + + hpplay.c + libsst.c + libsst.h + libst.h + linuxplay.c + nas.c + sgiplay.c + sound.c + sunplay.c + + These files implement the ability to play various sounds on some +types of computers. You have to configure your XEmacs with sound +support in order to get this capability. + + `sound.c' provides the generic interface. It implements various +Lisp primitives and variables that let you specify which sounds should +be played in certain conditions. (The conditions are identified by +symbols, which are passed to `ding' to make a sound. Various standard +functions call this function at certain times; if sound support does +not exist, a simple beep results. + + `sgiplay.c', `sunplay.c', `hpplay.c', and `linuxplay.c' interface to +the machine's speaker for various different kind of machines. This is +called "native" sound. + + `nas.c' interfaces to a computer somewhere else on the network using +the NAS (Network Audio Server) protocol, playing sounds on that +machine. This allows you to run XEmacs on a remote machine, with its +display set to your local machine, and have the sounds be made on your +local machine, provided that you have a NAS server running on your local +machine. + + `libsst.c', `libsst.h', and `libst.h' provide some additional +functions for playing sound on a Sun SPARC but are not currently in use. + + tooltalk.c + tooltalk.h + + These two modules implement an interface to the ToolTalk protocol, +which is an interprocess communication protocol implemented on some +versions of Unix. ToolTalk is a high-level protocol that allows +processes to register themselves as providers of particular services; +other processes can then request a service without knowing or caring +exactly who is providing the service. It is similar in spirit to the +DDE protocol provided under Microsoft Windows. ToolTalk is a part of +the new CDE (Common Desktop Environment) specification and is used to +connect the parts of the SPARCWorks development environment. + + getloadavg.c + + This module provides the ability to retrieve the system's current +load average. (The way to do this is highly system-specific, +unfortunately, and requires a lot of special-case code.) + + sunpro.c + + This module provides a small amount of code used internally at Sun to +keep statistics on the usage of XEmacs. + + broken-sun.h + strcmp.c + strcpy.c + sunOS-fix.c + + These files provide replacement functions and prototypes to fix +numerous bugs in early releases of SunOS 4.1. + + hftctl.c + + This module provides some terminal-control code necessary on +versions of AIX prior to 4.1. + + +File: internals.info, Node: Modules for Interfacing with X Windows, Next: Modules for Internationalization, Prev: Modules for Interfacing with the Operating System, Up: A Summary of the Various XEmacs Modules + +Modules for Interfacing with X Windows +====================================== + + Emacs.ad.h + + A file generated from `Emacs.ad', which contains XEmacs-supplied +fallback resources (so that XEmacs has pretty defaults). + + EmacsFrame.c + EmacsFrame.h + EmacsFrameP.h + + These modules implement an Xt widget class that encapsulates a frame. +This is for ease in integrating with Xt. The EmacsFrame widget covers +the entire X window except for the menubar; the scrollbars are +positioned on top of the EmacsFrame widget. + + *Warning:* Abandon hope, all ye who enter here. This code took an +ungodly amount of time to get right, and is likely to fall apart +mercilessly at the slightest change. Such is life under Xt. + + EmacsManager.c + EmacsManager.h + EmacsManagerP.h + + These modules implement a simple Xt manager (i.e. composite) widget +class that simply lets its children set whatever geometry they want. +It's amazing that Xt doesn't provide this standardly, but on second +thought, it makes sense, considering how amazingly broken Xt is. + + EmacsShell-sub.c + EmacsShell.c + EmacsShell.h + EmacsShellP.h + + These modules implement two Xt widget classes that are subclasses of +the TopLevelShell and TransientShell classes. This is necessary to deal +with more brokenness that Xt has sadistically thrust onto the backs of +developers. + + xgccache.c + xgccache.h + + These modules provide functions for maintenance and caching of GC's +(graphics contexts) under the X Window System. This code is junky and +needs to be rewritten. + + select-msw.c + select-x.c + select.c + select.h + + This module provides an interface to the X Window System's concept of +"selections", the standard way for X applications to communicate with +each other. + + xintrinsic.h + xintrinsicp.h + xmmanagerp.h + xmprimitivep.h + + These header files are similar in spirit to the `sys*.h' files and +buffer against different implementations of Xt and Motif. + + * `xintrinsic.h' should be included in place of `'. + + * `xintrinsicp.h' should be included in place of `'. + + * `xmmanagerp.h' should be included in place of `'. + + * `xmprimitivep.h' should be included in place of `'. + + xmu.c + xmu.h + + These files provide an emulation of the Xmu library for those systems +(i.e. HPUX) that don't provide it as a standard part of X. + + ExternalClient-Xlib.c + ExternalClient.c + ExternalClient.h + ExternalClientP.h + ExternalShell.c + ExternalShell.h + ExternalShellP.h + extw-Xlib.c + extw-Xlib.h + extw-Xt.c + extw-Xt.h + + These files provide the "external widget" interface, which allows an +XEmacs frame to appear as a widget in another application. To do this, +you have to configure with `--external-widget'. + + `ExternalShell*' provides the server (XEmacs) side of the connection. + + `ExternalClient*' provides the client (other application) side of +the connection. These files are not compiled into XEmacs but are +compiled into libraries that are then linked into your application. + + `extw-*' is common code that is used for both the client and server. + + Don't touch this code; something is liable to break if you do. + + +File: internals.info, Node: Modules for Internationalization, Next: Modules for Regression Testing, Prev: Modules for Interfacing with X Windows, Up: A Summary of the Various XEmacs Modules + +Modules for Internationalization +================================ + + mule-canna.c + mule-ccl.c + mule-charset.c + mule-charset.h + file-coding.c + file-coding.h + mule-mcpath.c + mule-mcpath.h + mule-wnnfns.c + mule.c + + These files implement the MULE (Asian-language) support. Note that +MULE actually provides a general interface for all sorts of languages, +not just Asian languages (although they are generally the most +complicated to support). This code is still in beta. + + `mule-charset.*' and `file-coding.*' provide the heart of the XEmacs +MULE support. `mule-charset.*' implements the "charset" Lisp object +type, which encapsulates a character set (an ordered one- or +two-dimensional set of characters, such as US ASCII or JISX0208 Japanese +Kanji). + + `file-coding.*' implements the "coding-system" Lisp object type, +which encapsulates a method of converting between different encodings. +An encoding is a representation of a stream of characters, possibly +from multiple character sets, using a stream of bytes or words, and +defines (e.g.) which escape sequences are used to specify particular +character sets, how the indices for a character are converted into bytes +(sometimes this involves setting the high bit; sometimes complicated +rearranging of the values takes place, as in the Shift-JIS encoding), +etc. + + `mule-ccl.c' provides the CCL (Code Conversion Language) +interpreter. CCL is similar in spirit to Lisp byte code and is used to +implement converters for custom encodings. + + `mule-canna.c' and `mule-wnnfns.c' implement interfaces to external +programs used to implement the Canna and WNN input methods, +respectively. This is currently in beta. + + `mule-mcpath.c' provides some functions to allow for pathnames +containing extended characters. This code is fragmentary, obsolete, and +completely non-working. Instead, `pathname-coding-system' is used to +specify conversions of names of files and directories. The standard C +I/O functions like `open()' are wrapped so that conversion occurs +automatically. + + `mule.c' provides a few miscellaneous things that should probably be +elsewhere. + + intl.c + + This provides some miscellaneous internationalization code for +implementing message translation and interfacing to the Ximp input +method. None of this code is currently working. + + iso-wide.h + + This contains leftover code from an earlier implementation of +Asian-language support, and is not currently used. + + +File: internals.info, Node: Modules for Regression Testing, Prev: Modules for Internationalization, Up: A Summary of the Various XEmacs Modules + +Modules for Regression Testing +============================== + + test-harness.el + base64-tests.el + byte-compiler-tests.el + case-tests.el + ccl-tests.el + c-tests.el + database-tests.el + extent-tests.el + hash-table-tests.el + lisp-tests.el + md5-tests.el + mule-tests.el + regexp-tests.el + symbol-tests.el + syntax-tests.el + + `test-harness.el' defines the macros `Assert', `Check-Error', +`Check-Error-Message', and `Check-Message'. The other files are test +files, testing various XEmacs modules. + + +File: internals.info, Node: Allocation of Objects in XEmacs Lisp, Next: Dumping, Prev: A Summary of the Various XEmacs Modules, Up: Top + +Allocation of Objects in XEmacs Lisp +************************************ + +* Menu: + +* Introduction to Allocation:: +* Garbage Collection:: +* GCPROing:: +* Garbage Collection - Step by Step:: +* Integers and Characters:: +* Allocation from Frob Blocks:: +* lrecords:: +* Low-level allocation:: +* Cons:: +* Vector:: +* Bit Vector:: +* Symbol:: +* Marker:: +* String:: +* Compiled Function:: + + +File: internals.info, Node: Introduction to Allocation, Next: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp + +Introduction to Allocation +========================== + +Emacs Lisp, like all Lisps, has garbage collection. This means that +the programmer never has to explicitly free (destroy) an object; it +happens automatically when the object becomes inaccessible. Most +experts agree that garbage collection is a necessity in a modern, +high-level language. Its omission from C stems from the fact that C was +originally designed to be a nice abstract layer on top of assembly +language, for writing kernels and basic system utilities rather than +large applications. + + Lisp objects can be created by any of a number of Lisp primitives. +Most object types have one or a small number of basic primitives for +creating objects. For conses, the basic primitive is `cons'; for +vectors, the primitives are `make-vector' and `vector'; for symbols, +the primitives are `make-symbol' and `intern'; etc. Some Lisp objects, +especially those that are primarily used internally, have no +corresponding Lisp primitives. Every Lisp object, though, has at least +one C primitive for creating it. + + Recall from section (VII) that a Lisp object, as stored in a 32-bit +or 64-bit word, has a few tag bits, and a "value" that occupies the +remainder of the bits. We can separate the different Lisp object types +into three broad categories: + + * (a) Those for whom the value directly represents the contents of + the Lisp object. Only two types are in this category: integers and + characters. No special allocation or garbage collection is + necessary for such objects. Lisp objects of these types do not + need to be `GCPRO'ed. + + In the remaining two categories, the type is stored in the object +itself. The tag for all such objects is the generic "lrecord" +(Lisp_Type_Record) tag. The first bytes of the object's structure are +an integer (actually a char) characterising the object's type and some +flags, in particular the mark bit used for garbage collection. A +structure describing the type is accessible thru the +lrecord_implementation_table indexed with said integer. This structure +includes the method pointers and a pointer to a string naming the type. + + * (b) Those lrecords that are allocated in frob blocks (see above). + This includes the objects that are most common and relatively + small, and includes conses, strings, subrs, floats, compiled + functions, symbols, extents, events, and markers. With the + cleanup of frob blocks done in 19.12, it's not terribly hard to + add more objects to this category, but it's a bit trickier than + adding an object type to type (c) (esp. if the object needs a + finalization method), and is not likely to save much space unless + the object is small and there are many of them. (In fact, if there + are very few of them, it might actually waste space.) + + * (c) Those lrecords that are individually `malloc()'ed. These are + called "lcrecords". All other types are in this category. Adding + a new type to this category is comparatively easy, and all types + added since 19.8 (when the current allocation scheme was devised, + by Richard Mlynarik), with the exception of the character type, + have been in this category. + + Note that bit vectors are a bit of a special case. They are simple +lrecords as in category (b), but are individually `malloc()'ed like +vectors. You can basically view them as exactly like vectors except +that their type is stored in lrecord fashion rather than in +directly-tagged fashion. + + +File: internals.info, Node: Garbage Collection, Next: GCPROing, Prev: Introduction to Allocation, Up: Allocation of Objects in XEmacs Lisp + +Garbage Collection +================== + +Garbage collection is simple in theory but tricky to implement. Emacs +Lisp uses the oldest garbage collection method, called "mark and +sweep". Garbage collection begins by starting with all accessible +locations (i.e. all variables and other slots where Lisp objects might +occur) and recursively traversing all objects accessible from those +slots, marking each one that is found. We then go through all of +memory and free each object that is not marked, and unmarking each +object that is marked. Note that "all of memory" means all currently +allocated objects. Traversing all these objects means traversing all +frob blocks, all vectors (which are chained in one big list), and all +lcrecords (which are likewise chained). + + Garbage collection can be invoked explicitly by calling +`garbage-collect' but is also called automatically by `eval', once a +certain amount of memory has been allocated since the last garbage +collection (according to `gc-cons-threshold'). + + +File: internals.info, Node: GCPROing, Next: Garbage Collection - Step by Step, Prev: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp + +`GCPRO'ing +========== + +`GCPRO'ing is one of the ugliest and trickiest parts of Emacs +internals. The basic idea is that whenever garbage collection occurs, +all in-use objects must be reachable somehow or other from one of the +roots of accessibility. The roots of accessibility are: + + 1. All objects that have been `staticpro()'d or + `staticpro_nodump()'ed. This is used for any global C variables + that hold Lisp objects. A call to `staticpro()' happens implicitly + as a result of any symbols declared with `defsymbol()' and any + variables declared with `DEFVAR_FOO()'. You need to explicitly + call `staticpro()' (in the `vars_of_foo()' method of a module) for + other global C variables holding Lisp objects. (This typically + includes internal lists and such things.). Use + `staticpro_nodump()' only in the rare cases when you do not want + the pointed variable to be saved at dump time but rather recompute + it at startup. + + Note that `obarray' is one of the `staticpro()'d things. + Therefore, all functions and variables get marked through this. + + 2. Any shadowed bindings that are sitting on the `specpdl' stack. + + 3. Any objects sitting in currently active (Lisp) stack frames, + catches, and condition cases. + + 4. A couple of special-case places where active objects are located. + + 5. Anything currently marked with `GCPRO'. + + Marking with `GCPRO' is necessary because some C functions (quite a +lot, in fact), allocate objects during their operation. Quite +frequently, there will be no other pointer to the object while the +function is running, and if a garbage collection occurs and the object +needs to be referenced again, bad things will happen. The solution is +to mark those objects with `GCPRO'. Unfortunately this is easy to +forget, and there is basically no way around this problem. Here are +some rules, though: + + 1. For every `GCPRON', there have to be declarations of `struct gcpro + gcpro1, gcpro2', etc. + + 2. You _must_ `UNGCPRO' anything that's `GCPRO'ed, and you _must not_ + `UNGCPRO' if you haven't `GCPRO'ed. Getting either of these wrong + will lead to crashes, often in completely random places unrelated + to where the problem lies. + + 3. The way this actually works is that all currently active `GCPRO's + are chained through the `struct gcpro' local variables, with the + variable `gcprolist' pointing to the head of the list and the nth + local `gcpro' variable pointing to the first `gcpro' variable in + the next enclosing stack frame. Each `GCPRO'ed thing is an + lvalue, and the `struct gcpro' local variable contains a pointer to + this lvalue. This is why things will mess up badly if you don't + pair up the `GCPRO's and `UNGCPRO's--you will end up with + `gcprolist's containing pointers to `struct gcpro's or local + `Lisp_Object' variables in no-longer-active stack frames. + + 4. It is actually possible for a single `struct gcpro' to protect a + contiguous array of any number of values, rather than just a + single lvalue. To effect this, call `GCPRON' as usual on the + first object in the array and then set `gcproN.nvars'. + + 5. *Strings are relocated.* What this means in practice is that the + pointer obtained using `XSTRING_DATA()' is liable to change at any + time, and you should never keep it around past any function call, + or pass it as an argument to any function that might cause a + garbage collection. This is why a number of functions accept + either a "non-relocatable" `char *' pointer or a relocatable Lisp + string, and only access the Lisp string's data at the very last + minute. In some cases, you may end up having to `alloca()' some + space and copy the string's data into it. + + 6. By convention, if you have to nest `GCPRO''s, use `NGCPRON' (along + with `struct gcpro ngcpro1, ngcpro2', etc.), `NNGCPRON', etc. + This avoids compiler warnings about shadowed locals. + + 7. It is _always_ better to err on the side of extra `GCPRO's rather + than too few. The extra cycles spent on this are almost never + going to make a whit of difference in the speed of anything. + + 8. The general rule to follow is that caller, not callee, `GCPRO's. + That is, you should not have to explicitly `GCPRO' any Lisp objects + that are passed in as parameters. + + One exception from this rule is if you ever plan to change the + parameter value, and store a new object in it. In that case, you + _must_ `GCPRO' the parameter, because otherwise the new object + will not be protected. + + So, if you create any Lisp objects (remember, this happens in all + sorts of circumstances, e.g. with `Fcons()', etc.), you are + responsible for `GCPRO'ing them, unless you are _absolutely sure_ + that there's no possibility that a garbage-collection can occur + while you need to use the object. Even then, consider `GCPRO'ing. + + 9. A garbage collection can occur whenever anything calls `Feval', or + whenever a QUIT can occur where execution can continue past this. + (Remember, this is almost anywhere.) + + 10. If you have the _least smidgeon of doubt_ about whether you need + to `GCPRO', you should `GCPRO'. + + 11. Beware of `GCPRO'ing something that is uninitialized. If you have + any shade of doubt about this, initialize all your variables to + `Qnil'. + + 12. Be careful of traps, like calling `Fcons()' in the argument to + another function. By the "caller protects" law, you should be + `GCPRO'ing the newly-created cons, but you aren't. A certain + number of functions that are commonly called on freshly created + stuff (e.g. `nconc2()', `Fsignal()'), break the "caller protects" + law and go ahead and `GCPRO' their arguments so as to simplify + things, but make sure and check if it's OK whenever doing + something like this. + + 13. Once again, remember to `GCPRO'! Bugs resulting from insufficient + `GCPRO'ing are intermittent and extremely difficult to track down, + often showing up in crashes inside of `garbage-collect' or in + weirdly corrupted objects or even in incorrect values in a totally + different section of code. + + If you don't understand whether to `GCPRO' in a particular instance, +ask on the mailing lists. A general hint is that `prog1' is the +canonical example. + + Given the extremely error-prone nature of the `GCPRO' scheme, and +the difficulties in tracking down, it should be considered a deficiency +in the XEmacs code. A solution to this problem would involve +implementing so-called "conservative" garbage collection for the C +stack. That involves looking through all of stack memory and treating +anything that looks like a reference to an object as a reference. This +will result in a few objects not getting collected when they should, but +it obviates the need for `GCPRO'ing, and allows garbage collection to +happen at any point at all, such as during object allocation. + + +File: internals.info, Node: Garbage Collection - Step by Step, Next: Integers and Characters, Prev: GCPROing, Up: Allocation of Objects in XEmacs Lisp + +Garbage Collection - Step by Step +================================= + +* Menu: + +* Invocation:: +* garbage_collect_1:: +* mark_object:: +* gc_sweep:: +* sweep_lcrecords_1:: +* compact_string_chars:: +* sweep_strings:: +* sweep_bit_vectors_1:: + + +File: internals.info, Node: Invocation, Next: garbage_collect_1, Up: Garbage Collection - Step by Step + +Invocation +---------- + +The first thing that anyone should know about garbage collection is: +when and how the garbage collector is invoked. One might think that this +could happen every time new memory is allocated, e.g. new objects are +created, but this is _not_ the case. Instead, we have the following +situation: + + The entry point of any process of garbage collection is an invocation +of the function `garbage_collect_1' in file `alloc.c'. The invocation +can occur _explicitly_ by calling the function `Fgarbage_collect' (in +addition this function provides information about the freed memory), or +can occur _implicitly_ in four different situations: + 1. In function `main_1' in file `emacs.c'. This function is called at + each startup of xemacs. The garbage collection is invoked after all + initial creations are completed, but only if a special internal + error checking-constant `ERROR_CHECK_GC' is defined. + + 2. In function `disksave_object_finalization' in file `alloc.c'. The + only purpose of this function is to clear the objects from memory + which need not be stored with xemacs when we dump out an + executable. This is only done by `Fdump_emacs' or by + `Fdump_emacs_data' respectively (both in `emacs.c'). The actual + clearing is accomplished by making these objects unreachable and + starting a garbage collection. The function is only used while + building xemacs. + + 3. In function `Feval / eval' in file `eval.c'. Each time the well + known and often used function eval is called to evaluate a form, + one of the first things that could happen, is a potential call of + `garbage_collect_1'. There exist three global variables, + `consing_since_gc' (counts the created cons-cells since the last + garbage collection), `gc_cons_threshold' (a specified threshold + after which a garbage collection occurs) and `always_gc'. If + `always_gc' is set or if the threshold is exceeded, the garbage + collection will start. + + 4. In function `Ffuncall / funcall' in file `eval.c'. This function + evaluates calls of elisp functions and works according to `Feval'. + + The upshot is that garbage collection can basically occur everywhere +`Feval', respectively `Ffuncall', is used - either directly or through +another function. Since calls to these two functions are hidden in +various other functions, many calls to `garbage_collect_1' are not +obviously foreseeable, and therefore unexpected. Instances where they +are used that are worth remembering are various elisp commands, as for +example `or', `and', `if', `cond', `while', `setq', etc., miscellaneous +`gui_item_...' functions, everything related to `eval' (`Feval_buffer', +`call0', ...) and inside `Fsignal'. The latter is used to handle +signals, as for example the ones raised by every `QUIT'-macro triggered +after pressing Ctrl-g. + + +File: internals.info, Node: garbage_collect_1, Next: mark_object, Prev: Invocation, Up: Garbage Collection - Step by Step + +`garbage_collect_1' +------------------- + +We can now describe exactly what happens after the invocation takes +place. + 1. There are several cases in which the garbage collector is left + immediately: when we are already garbage collecting + (`gc_in_progress'), when the garbage collection is somehow + forbidden (`gc_currently_forbidden'), when we are currently + displaying something (`in_display') or when we are preparing for + the armageddon of the whole system (`preparing_for_armageddon'). + + 2. Next the correct frame in which to put all the output occurring + during garbage collecting is determined. In order to be able to + restore the old display's state after displaying the message, some + data about the current cursor position has to be saved. The + variables `pre_gc_cursor' and `cursor_changed' take care of that. + + 3. The state of `gc_currently_forbidden' must be restored after the + garbage collection, no matter what happens during the process. We + accomplish this by `record_unwind_protect'ing the suitable function + `restore_gc_inhibit' together with the current value of + `gc_currently_forbidden'. + + 4. If we are concurrently running an interactive xemacs session, the + next step is simply to show the garbage collector's cursor/message. + + 5. The following steps are the intrinsic steps of the garbage + collector, therefore `gc_in_progress' is set. + + 6. For debugging purposes, it is possible to copy the current C stack + frame. However, this seems to be a currently unused feature. + + 7. Before actually starting to go over all live objects, references to + objects that are no longer used are pruned. We only have to do + this for events (`clear_event_resource') and for specifiers + (`cleanup_specifiers'). + + 8. Now the mark phase begins and marks all accessible elements. In + order to start from all slots that serve as roots of + accessibility, the function `mark_object' is called for each root + individually to go out from there to mark all reachable objects. + All roots that are traversed are shown in their processed order: + * all constant symbols and static variables that are registered + via `staticpro' in the dynarr `staticpros'. *Note Adding + Global Lisp Variables::. + + * all Lisp objects that are created in C functions and that + must be protected from freeing them. They are registered in + the global list `gcprolist'. *Note GCPROing::. + + * all local variables (i.e. their name fields `symbol' and old + values `old_values') that are bound during the evaluation by + the Lisp engine. They are stored in `specbinding' structs + pushed on a stack called `specpdl'. *Note Dynamic Binding; + The specbinding Stack; Unwind-Protects::. + + * all catch blocks that the Lisp engine encounters during the + evaluation cause the creation of structs `catchtag' inserted + in the list `catchlist'. Their tag (`tag') and value (`val' + fields are freshly created objects and therefore have to be + marked. *Note Catch and Throw::. + + * every function application pushes new structs `backtrace' on + the call stack of the Lisp engine (`backtrace_list'). The + unique parts that have to be marked are the fields for each + function (`function') and all their arguments (`args'). + *Note Evaluation::. + + * all objects that are used by the redisplay engine that must + not be freed are marked by a special function called + `mark_redisplay' (in `redisplay.c'). + + * all objects created for profiling purposes are allocated by C + functions instead of using the lisp allocation mechanisms. In + order to receive the right ones during the sweep phase, they + also have to be marked manually. That is done by the function + `mark_profiling_info' + + 9. Hash tables in XEmacs belong to a kind of special objects that + make use of a concept often called 'weak pointers'. To make a + long story short, these kind of pointers are not followed during + the estimation of the live objects during garbage collection. Any + object referenced only by weak pointers is collected anyway, and + the reference to it is cleared. In hash tables there are different + usage patterns of them, manifesting in different types of hash + tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak' + (internally also 'key-car-weak' and 'value-car-weak') hash tables, + each clearing entries depending on different conditions. More + information can be found in the documentation to the function + `make-hash-table'. + + Because there are complicated dependency rules about when and what + to mark while processing weak hash tables, the standard `marker' + method is only active if it is marking non-weak hash tables. As + soon as a weak component is in the table, the hash table entries + are ignored while marking. Instead their marking is done each + separately by the function `finish_marking_weak_hash_tables'. This + function iterates over each hash table entry `hentries' for each + weak hash table in `Vall_weak_hash_tables'. Depending on the type + of a table, the appropriate action is performed. If a table is + acting as `HASH_TABLE_KEY_WEAK', and a key already marked, + everything reachable from the `value' component is marked. If it is + acting as a `HASH_TABLE_VALUE_WEAK' and the value component is + already marked, the marking starts beginning only from the `key' + component. If it is a `HASH_TABLE_KEY_CAR_WEAK' and the car of + the key entry is already marked, we mark both the `key' and + `value' components. Finally, if the table is of the type + `HASH_TABLE_VALUE_CAR_WEAK' and the car of the value components is + already marked, again both the `key' and the `value' components + get marked. + + Again, there are lists with comparable properties called weak + lists. There exist different peculiarities of their types called + `simple', `assoc', `key-assoc' and `value-assoc'. You can find + further details about them in the description to the function + `make-weak-list'. The scheme of their marking is similar: all weak + lists are listed in `Qall_weak_lists', therefore we iterate over + them. The marking is advanced until we hit an already marked pair. + Then we know that during a former run all the rest has been marked + completely. Again, depending on the special type of the weak list, + our jobs differ. If it is a `WEAK_LIST_SIMPLE' and the elem is + marked, we mark the `cons' part. If it is a `WEAK_LIST_ASSOC' and + not a pair or a pair with both marked car and cdr, we mark the + `cons' and the `elem'. If it is a `WEAK_LIST_KEY_ASSOC' and not a + pair or a pair with a marked car of the elem, we mark the `cons' + and the `elem'. Finally, if it is a `WEAK_LIST_VALUE_ASSOC' and + not a pair or a pair with a marked cdr of the elem, we mark both + the `cons' and the `elem'. + + Since, by marking objects in reach from weak hash tables and weak + lists, other objects could get marked, this perhaps implies + further marking of other weak objects, both finishing functions + are redone as long as yet unmarked objects get freshly marked. + + 10. After completing the special marking for the weak hash tables and + for the weak lists, all entries that point to objects that are + going to be swept in the further process are useless, and + therefore have to be removed from the table or the list. + + The function `prune_weak_hash_tables' does the job for weak hash + tables. Totally unmarked hash tables are removed from the list + `Vall_weak_hash_tables'. The other ones are treated more carefully + by scanning over all entries and removing one as soon as one of + the components `key' and `value' is unmarked. + + The same idea applies to the weak lists. It is accomplished by + `prune_weak_lists': An unmarked list is pruned from + `Vall_weak_lists' immediately. A marked list is treated more + carefully by going over it and removing just the unmarked pairs. + + 11. The function `prune_specifiers' checks all listed specifiers held + in `Vall_specifiers' and removes the ones from the lists that are + unmarked. + + 12. All syntax tables are stored in a list called + `Vall_syntax_tables'. The function `prune_syntax_tables' walks + through it and unlinks the tables that are unmarked. + + 13. Next, we will attack the complete sweeping - the function + `gc_sweep' which holds the predominance. + + 14. First, all the variables with respect to garbage collection are + reset. `consing_since_gc' - the counter of the created cells since + the last garbage collection - is set back to 0, and + `gc_in_progress' is not `true' anymore. + + 15. In case the session is interactive, the displayed cursor and + message are removed again. + + 16. The state of `gc_inhibit' is restored to the former value by + unwinding the stack. + + 17. A small memory reserve is always held back that can be reached by + `breathing_space'. If nothing more is left, we create a new reserve + and exit. + + +File: internals.info, Node: mark_object, Next: gc_sweep, Prev: garbage_collect_1, Up: Garbage Collection - Step by Step + +`mark_object' +------------- + +The first thing that is checked while marking an object is whether the +object is a real Lisp object `Lisp_Type_Record' or just an integer or a +character. Integers and characters are the only two types that are +stored directly - without another level of indirection, and therefore +they don't have to be marked and collected. *Note How Lisp Objects Are +Represented in C::. + + The second case is the one we have to handle. It is the one when we +are dealing with a pointer to a Lisp object. But, there exist also three +possibilities, that prevent us from doing anything while marking: The +object is read only which prevents it from being garbage collected, +i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is +already marked, and need not be marked for the second time (checked by +`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object +(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit +in some const space, and can therefore not be marked, see +`this_one_is_unmarkable' in `alloc.c'). + + Now, the actual marking is feasible. We do so by once using the macro +`MARK_RECORD_HEADER' to mark the object itself (actually the special +flag in the lrecord header), and calling its special marker "method" +`marker' if available. The marker method marks every other object that +is in reach from our current object. Note, that these marker methods +should not call `mark_object' recursively, but instead should return +the next object from where further marking has to be performed. + + In case another object was returned, as mentioned before, we +reiterate the whole `mark_object' process beginning with this next +object. + + +File: internals.info, Node: gc_sweep, Next: sweep_lcrecords_1, Prev: mark_object, Up: Garbage Collection - Step by Step + +`gc_sweep' +---------- + +The job of this function is to free all unmarked records from memory. As +we know, there are different types of objects implemented and managed, +and consequently different ways to free them from memory. *Note +Introduction to Allocation::. + + We start with all objects stored through `lcrecords'. All bulkier +objects are allocated and handled using that scheme of `lcrecords'. +Each object is `malloc'ed separately instead of placing it in one of +the contiguous frob blocks. All types that are currently stored using +`lcrecords''s `alloc_lcrecord' and `make_lcrecord_list' are the types: +vectors, buffers, char-table, char-table-entry, console, weak-list, +database, device, ldap, hash-table, command-builder, extent-auxiliary, +extent-info, face, coding-system, frame, image-instance, glyph, +popup-data, gui-item, keymap, charset, color_instance, font_instance, +opaque, opaque-list, process, range-table, specifier, +symbol-value-buffer-local, symbol-value-lisp-magic, +symbol-value-varalias, toolbar-button, tooltalk-message, +tooltalk-pattern, window, and window-configuration. We take care of +them in the fist place in order to be able to handle and to finalize +items stored in them more easily. The function `sweep_lcrecords_1' as +described below is doing the whole job for us. For a description about +the internals: *Note lrecords::. + + Our next candidates are the other objects that behave quite +differently than everything else: the strings. They consists of two +parts, a fixed-size portion (`struct Lisp_String') holding the string's +length, its property list and a pointer to the second part, and the +actual string data, which is stored in string-chars blocks comparable to +frob blocks. In this block, the data is not only freed, but also a +compression of holes is made, i.e. all strings are relocated together. +*Note String::. This compacting phase is performed by the function +`compact_string_chars', the actual sweeping by the function +`sweep_strings' is described below. + + After that, the other types are swept step by step using functions +`sweep_conses', `sweep_bit_vectors_1', `sweep_compiled_functions', +`sweep_floats', `sweep_symbols', `sweep_extents', `sweep_markers' and +`sweep_extents'. They are the fixed-size types cons, floats, +compiled-functions, symbol, marker, extent, and event stored in +so-called "frob blocks", and therefore we can basically do the same on +every type objects, using the same macros, especially defined only to +handle everything with respect to fixed-size blocks. The only fixed-size +type that is not handled here are the fixed-size portion of strings, +because we took special care of them earlier. + + The only big exceptions are bit vectors stored differently and +therefore treated differently by the function `sweep_bit_vectors_1' +described later. + + At first, we need some brief information about how these fixed-size +types are managed in general, in order to understand how the sweeping +is done. They have all a fixed size, and are therefore stored in big +blocks of memory - allocated at once - that can hold a certain amount +of objects of one type. The macro `DECLARE_FIXED_TYPE_ALLOC' creates +the suitable structures for every type. More precisely, we have the +block struct (holding a pointer to the previous block `prev' and the +objects in `block[]'), a pointer to current block +(`current_..._block)') and its last index (`current_..._block_index'), +and a pointer to the free list that will be created. Also a macro +`FIXED_TYPE_FROM_BLOCK' plus some related macros exists that are used +to obtain a new object, either from the free list +`ALLOCATE_FIXED_TYPE_1' if there is an unused object of that type +stored or by allocating a completely new block using +`ALLOCATE_FIXED_TYPE_FROM_BLOCK'. + + The rest works as follows: all of them define a macro `UNMARK_...' +that is used to unmark the object. They define a macro +`ADDITIONAL_FREE_...' that defines additional work that has to be done +when converting an object from in use to not in use (so far, only +markers use it in order to unchain them). Then, they all call the macro +`SWEEP_FIXED_TYPE_BLOCK' instantiated with their type name and their +struct name. + + This call in particular does the following: we go over all blocks +starting with the current moving towards the oldest. For each block, +we look at every object in it. If the object already freed (checked +with `FREE_STRUCT_P' using the first pointer of the object), or if it is +set to read only (`C_READONLY_RECORD_HEADER_P', nothing must be done. +If it is unmarked (checked with `MARKED_RECORD_HEADER_P'), it is put in +the free list and set free (using the macro `FREE_FIXED_TYPE', +otherwise it stays in the block, but is unmarked (by `UNMARK_...'). +While going through one block, we note if the whole block is empty. If +so, the whole block is freed (using `xfree') and the free list state is +set to the state it had before handling this block. + + +File: internals.info, Node: sweep_lcrecords_1, Next: compact_string_chars, Prev: gc_sweep, Up: Garbage Collection - Step by Step + +`sweep_lcrecords_1' +------------------- + +After nullifying the complete lcrecord statistics, we go over all +lcrecords two separate times. They are all chained together in a list +with a head called `all_lcrecords'. + + The first loop calls for each object its `finalizer' method, but only +in the case that it is not read only (`C_READONLY_RECORD_HEADER_P)', it +is not already marked (`MARKED_RECORD_HEADER_P'), it is not already in +a free list (list of freed objects, field `free') and finally it owns a +finalizer method. + + The second loop actually frees the appropriate objects again by +iterating through the whole list. In case an object is read only or +marked, it has to persist, otherwise it is manually freed by calling +`xfree'. During this loop, the lcrecord statistics are kept up to date +by calling `tick_lcrecord_stats' with the right arguments, + + +File: internals.info, Node: compact_string_chars, Next: sweep_strings, Prev: sweep_lcrecords_1, Up: Garbage Collection - Step by Step + +`compact_string_chars' +---------------------- + +The purpose of this function is to compact all the data parts of the +strings that are held in so-called `string_chars_block', i.e. the +strings that do not exceed a certain maximal length. + + The procedure with which this is done is as follows. We are keeping +two positions in the `string_chars_block's using two pointer/integer +pairs, namely `from_sb'/`from_pos' and `to_sb'/`to_pos'. They stand for +the actual positions, from where to where, to copy the actually handled +string. + + While going over all chained `string_char_block's and their held +strings, staring at `first_string_chars_block', both pointers are +advanced and eventually a string is copied from `from_sb' to `to_sb', +depending on the status of the pointed at strings. + + More precisely, we can distinguish between the following actions. + * The string at `from_sb''s position could be marked as free, which + is indicated by an invalid pointer to the pointer that should + point back to the fixed size string object, and which is checked by + `FREE_STRUCT_P'. In this case, the `from_sb'/`from_pos' is + advanced to the next string, and nothing has to be copied. + + * Also, if a string object itself is unmarked, nothing has to be + copied. We likewise advance the `from_sb'/`from_pos' pair as + described above. + + * In all other cases, we have a marked string at hand. The string + data must be moved from the from-position to the to-position. In + case there is not enough space in the actual `to_sb'-block, we + advance this pointer to the beginning of the next block before + copying. In case the from and to positions are different, we + perform the actual copying using the library function `memmove'. + + After compacting, the pointer to the current `string_chars_block', +sitting in `current_string_chars_block', is reset on the last block to +which we moved a string, i.e. `to_block', and all remaining blocks (we +know that they just carry garbage) are explicitly `xfree'd. + + +File: internals.info, Node: sweep_strings, Next: sweep_bit_vectors_1, Prev: compact_string_chars, Up: Garbage Collection - Step by Step + +`sweep_strings' +--------------- + +The sweeping for the fixed sized string objects is essentially exactly +the same as it is for all other fixed size types. As before, the freeing +into the suitable free list is done by using the macro +`SWEEP_FIXED_SIZE_BLOCK' after defining the right macros +`UNMARK_string' and `ADDITIONAL_FREE_string'. These two definitions are +a little bit special compared to the ones used for the other fixed size +types. + + `UNMARK_string' is defined the same way except some additional code +used for updating the bookkeeping information. + + For strings, `ADDITIONAL_FREE_string' has to do something in +addition: in case, the string was not allocated in a +`string_chars_block' because it exceeded the maximal length, and +therefore it was `malloc'ed separately, we know also `xfree' it +explicitly. + + +File: internals.info, Node: sweep_bit_vectors_1, Prev: sweep_strings, Up: Garbage Collection - Step by Step + +`sweep_bit_vectors_1' +--------------------- + +Bit vectors are also one of the rare types that are `malloc'ed +individually. Consequently, while sweeping, all further needless bit +vectors must be freed by hand. This is done, as one might imagine, the +expected way: since they are all registered in a list called +`all_bit_vectors', all elements of that list are traversed, all +unmarked bit vectors are unlinked by calling `xfree' and all of them +become unmarked. In addition, the bookkeeping information used for +garbage collector's output purposes is updated. + + +File: internals.info, Node: Integers and Characters, Next: Allocation from Frob Blocks, Prev: Garbage Collection - Step by Step, Up: Allocation of Objects in XEmacs Lisp + +Integers and Characters +======================= + +Integer and character Lisp objects are created from integers using the +macros `XSETINT()' and `XSETCHAR()' or the equivalent functions +`make_int()' and `make_char()'. (These are actually macros on most +systems.) These functions basically just do some moving of bits +around, since the integral value of the object is stored directly in +the `Lisp_Object'. + + `XSETINT()' and the like will truncate values given to them that are +too big; i.e. you won't get the value you expected but the tag bits +will at least be correct. + + +File: internals.info, Node: Allocation from Frob Blocks, Next: lrecords, Prev: Integers and Characters, Up: Allocation of Objects in XEmacs Lisp + +Allocation from Frob Blocks +=========================== + +The uninitialized memory required by a `Lisp_Object' of a particular +type is allocated using `ALLOCATE_FIXED_TYPE()'. This only occurs +inside of the lowest-level object-creating functions in `alloc.c': +`Fcons()', `make_float()', `Fmake_byte_code()', `Fmake_symbol()', +`allocate_extent()', `allocate_event()', `Fmake_marker()', and +`make_uninit_string()'. The idea is that, for each type, there are a +number of frob blocks (each 2K in size); each frob block is divided up +into object-sized chunks. Each frob block will have some of these +chunks that are currently assigned to objects, and perhaps some that are +free. (If a frob block has nothing but free chunks, it is freed at the +end of the garbage collection cycle.) The free chunks are stored in a +free list, which is chained by storing a pointer in the first four bytes +of the chunk. (Except for the free chunks at the end of the last frob +block, which are handled using an index which points past the end of the +last-allocated chunk in the last frob block.) `ALLOCATE_FIXED_TYPE()' +first tries to retrieve a chunk from the free list; if that fails, it +calls `ALLOCATE_FIXED_TYPE_FROM_BLOCK()', which looks at the end of the +last frob block for space, and creates a new frob block if there is +none. (There are actually two versions of these macros, one of which is +more defensive but less efficient and is used for error-checking.) + + +File: internals.info, Node: lrecords, Next: Low-level allocation, Prev: Allocation from Frob Blocks, Up: Allocation of Objects in XEmacs Lisp + +lrecords +======== + +[see `lrecord.h'] + + All lrecords have at the beginning of their structure a `struct +lrecord_header'. This just contains a type number and some flags, +including the mark bit. All builtin type numbers are defined as +constants in `enum lrecord_type', to allow the compiler to generate +more efficient code for `TYPEP'. The type number, thru the +`lrecord_implementation_table', gives access to a `struct +lrecord_implementation', which is a structure containing method pointers +and such. There is one of these for each type, and it is a global, +constant, statically-declared structure that is declared in the +`DEFINE_LRECORD_IMPLEMENTATION()' macro. + + Simple lrecords (of type (b) above) just have a `struct +lrecord_header' at their beginning. lcrecords, however, actually have a +`struct lcrecord_header'. This, in turn, has a `struct lrecord_header' +at its beginning, so sanity is preserved; but it also has a pointer +used to chain all lcrecords together, and a special ID field used to +distinguish one lcrecord from another. (This field is used only for +debugging and could be removed, but the space gain is not significant.) + + Simple lrecords are created using `ALLOCATE_FIXED_TYPE()', just like +for other frob blocks. The only change is that the implementation +pointer must be initialized correctly. (The implementation structure for +an lrecord, or rather the pointer to it, is named `lrecord_float', +`lrecord_extent', `lrecord_buffer', etc.) + + lcrecords are created using `alloc_lcrecord()'. This takes a size +to allocate and an implementation pointer. (The size needs to be passed +because some lcrecords, such as window configurations, are of variable +size.) This basically just `malloc()'s the storage, initializes the +`struct lcrecord_header', and chains the lcrecord onto the head of the +list of all lcrecords, which is stored in the variable `all_lcrecords'. +The calls to `alloc_lcrecord()' generally occur in the lowest-level +allocation function for each lrecord type. + + Whenever you create an lrecord, you need to call either +`DEFINE_LRECORD_IMPLEMENTATION()' or +`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()'. This needs to be specified +in a `.c' file, at the top level. What this actually does is define +and initialize the implementation structure for the lrecord. (And +possibly declares a function `error_check_foo()' that implements the +`XFOO()' macro when error-checking is enabled.) The arguments to the +macros are the actual type name (this is used to construct the C +variable name of the lrecord implementation structure and related +structures using the `##' macro concatenation operator), a string that +names the type on the Lisp level (this may not be the same as the C +type name; typically, the C type name has underscores, while the Lisp +string has dashes), various method pointers, and the name of the C +structure that contains the object. The methods are used to +encapsulate type-specific information about the object, such as how to +print it or mark it for garbage collection, so that it's easy to add +new object types without having to add a specific case for each new +type in a bunch of different places. + + The difference between `DEFINE_LRECORD_IMPLEMENTATION()' and +`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()' is that the former is used +for fixed-size object types and the latter is for variable-size object +types. Most object types are fixed-size; some complex types, however +(e.g. window configurations), are variable-size. Variable-size object +types have an extra method, which is called to determine the actual +size of a particular object of that type. (Currently this is only used +for keeping allocation statistics.) + + For the purpose of keeping allocation statistics, the allocation +engine keeps a list of all the different types that exist. Note that, +since `DEFINE_LRECORD_IMPLEMENTATION()' is a macro that is specified at +top-level, there is no way for it to initialize the global data +structures containing type information, like +`lrecord_implementations_table'. For this reason a call to +`INIT_LRECORD_IMPLEMENTATION' must be added to the same source file +containing `DEFINE_LRECORD_IMPLEMENTATION', but instead of to the top +level, to one of the init functions, typically `syms_of_FOO.c'. +`INIT_LRECORD_IMPLEMENTATION' must be called before an object of this +type is used. + + The type number is also used to index into an array holding the +number of objects of each type and the total memory allocated for +objects of that type. The statistics in this array are computed during +the sweep stage. These statistics are returned by the call to +`garbage-collect'. + + Note that for every type defined with a `DEFINE_LRECORD_*()' macro, +there needs to be a `DECLARE_LRECORD_IMPLEMENTATION()' somewhere in a +`.h' file, and this `.h' file needs to be included by `inline.c'. + + Furthermore, there should generally be a set of `XFOOBAR()', +`FOOBARP()', etc. macros in a `.h' (or occasionally `.c') file. To +create one of these, copy an existing model and modify as necessary. + + *Please note:* If you define an lrecord in an external +dynamically-loaded module, you must use `DECLARE_EXTERNAL_LRECORD', +`DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION', and +`DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION' instead of the +non-EXTERNAL forms. These macros will dynamically add new type numbers +to the global enum that records them, whereas the non-EXTERNAL forms +assume that the programmer has already inserted the correct type numbers +into the enum's code at compile-time. + + The various methods in the lrecord implementation structure are: + + 1. A "mark" method. This is called during the marking stage and + passed a function pointer (usually the `mark_object()' function), + which is used to mark an object. All Lisp objects that are + contained within the object need to be marked by applying this + function to them. The mark method should also return a Lisp + object, which should be either `nil' or an object to mark. (This + can be used in lieu of calling `mark_object()' on the object, to + reduce the recursion depth, and consequently should be the most + heavily nested sub-object, such as a long list.) + + *Please note:* When the mark method is called, garbage collection + is in progress, and special precautions need to be taken when + accessing objects; see section (B) above. + + If your mark method does not need to do anything, it can be `NULL'. + + 2. A "print" method. This is called to create a printed + representation of the object, whenever `princ', `prin1', or the + like is called. It is passed the object, a stream to which the + output is to be directed, and an `escapeflag' which indicates + whether the object's printed representation should be "escaped" so + that it is readable. (This corresponds to the difference between + `princ' and `prin1'.) Basically, "escaped" means that strings will + have quotes around them and confusing characters in the strings + such as quotes, backslashes, and newlines will be backslashed; and + that special care will be taken to make symbols print in a + readable fashion (e.g. symbols that look like numbers will be + backslashed). Other readable objects should perhaps pass + `escapeflag' on when sub-objects are printed, so that readability + is preserved when necessary (or if not, always pass in a 1 for + `escapeflag'). Non-readable objects should in general ignore + `escapeflag', except that some use it as an indication that more + verbose output should be given. + + Sub-objects are printed using `print_internal()', which takes + exactly the same arguments as are passed to the print method. + + Literal C strings should be printed using `write_c_string()', or + `write_string_1()' for non-null-terminated strings. + + Functions that do not have a readable representation should check + the `print_readably' flag and signal an error if it is set. + + If you specify NULL for the print method, the + `default_object_printer()' will be used. + + 3. A "finalize" method. This is called at the beginning of the sweep + stage on lcrecords that are about to be freed, and should be used + to perform any extra object cleanup. This typically involves + freeing any extra `malloc()'ed memory associated with the object, + releasing any operating-system and window-system resources + associated with the object (e.g. pixmaps, fonts), etc. + + The finalize method can be NULL if nothing needs to be done. + + WARNING #1: The finalize method is also called at the end of the + dump phase; this time with the for_disksave parameter set to + non-zero. The object is _not_ about to disappear, so you have to + make sure to _not_ free any extra `malloc()'ed memory if you're + going to need it later. (Also, signal an error if there are any + operating-system and window-system resources here, because they + can't be dumped.) + + Finalize methods should, as a rule, set to zero any pointers after + they've been freed, and check to make sure pointers are not zero + before freeing. Although I'm pretty sure that finalize methods + are not called twice on the same object (except for the + `for_disksave' proviso), we've gotten nastily burned in some cases + by not doing this. + + WARNING #2: The finalize method is _only_ called for lcrecords, + _not_ for simply lrecords. If you need a finalize method for + simple lrecords, you have to stick it in the + `ADDITIONAL_FREE_foo()' macro in `alloc.c'. + + WARNING #3: Things are in an _extremely_ bizarre state when + `ADDITIONAL_FREE_foo()' is called, so you have to be incredibly + careful when writing one of these functions. See the comment in + `gc_sweep()'. If you ever have to add one of these, consider + using an lcrecord or dealing with the problem in a different + fashion. + + 4. An "equal" method. This compares the two objects for similarity, + when `equal' is called. It should compare the contents of the + objects in some reasonable fashion. It is passed the two objects + and a "depth" value, which is used to catch circular objects. To + compare sub-Lisp-objects, call `internal_equal()' and bump the + depth value by one. If this value gets too high, a + `circular-object' error will be signaled. + + If this is NULL, objects are `equal' only when they are `eq', i.e. + identical. + + 5. A "hash" method. This is used to hash objects when they are to be + compared with `equal'. The rule here is that if two objects are + `equal', they _must_ hash to the same value; i.e. your hash + function should use some subset of the sub-fields of the object + that are compared in the "equal" method. If you specify this + method as `NULL', the object's pointer will be used as the hash, + which will _fail_ if the object has an `equal' method, so don't do + this. + + To hash a sub-Lisp-object, call `internal_hash()'. Bump the depth + by one, just like in the "equal" method. + + To convert a Lisp object directly into a hash value (using its + pointer), use `LISP_HASH()'. This is what happens when the hash + method is NULL. + + To hash two or more values together into a single value, use + `HASH2()', `HASH3()', `HASH4()', etc. + + 6. "getprop", "putprop", "remprop", and "plist" methods. These are + used for object types that have properties. I don't feel like + documenting them here. If you create one of these objects, you + have to use different macros to define them, i.e. + `DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS()' or + `DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS()'. + + 7. A "size_in_bytes" method, when the object is of variable-size. + (i.e. declared with a `_SEQUENCE_IMPLEMENTATION' macro.) This + should simply return the object's size in bytes, exactly as you + might expect. For an example, see the methods for window + configurations and opaques. + + +File: internals.info, Node: Low-level allocation, Next: Cons, Prev: lrecords, Up: Allocation of Objects in XEmacs Lisp + +Low-level allocation +==================== + +Memory that you want to allocate directly should be allocated using +`xmalloc()' rather than `malloc()'. This implements error-checking on +the return value, and once upon a time did some more vital stuff (i.e. +`BLOCK_INPUT', which is no longer necessary). Free using `xfree()', +and realloc using `xrealloc()'. Note that `xmalloc()' will do a +non-local exit if the memory can't be allocated. (Many functions, +however, do not expect this, and thus XEmacs will likely crash if this +happens. *This is a bug.* If you can, you should strive to make your +function handle this OK. However, it's difficult in the general +circumstance, perhaps requiring extra unwind-protects and such.) + + Note that XEmacs provides two separate replacements for the standard +`malloc()' library function. These are called "old GNU malloc" +(`malloc.c') and "new GNU malloc" (`gmalloc.c'), respectively. New GNU +malloc is better in pretty much every way than old GNU malloc, and +should be used if possible. (It used to be that on some systems, the +old one worked but the new one didn't. I think this was due +specifically to a bug in SunOS, which the new one now works around; so +I don't think the old one ever has to be used any more.) The primary +difference between both of these mallocs and the standard system malloc +is that they are much faster, at the expense of increased space. The +basic idea is that memory is allocated in fixed chunks of powers of +two. This allows for basically constant malloc time, since the various +chunks can just be kept on a number of free lists. (The standard system +malloc typically allocates arbitrary-sized chunks and has to spend some +time, sometimes a significant amount of time, walking the heap looking +for a free block to use and cleaning things up.) The new GNU malloc +improves on things by allocating large objects in chunks of 4096 bytes +rather than in ever larger powers of two, which results in ever larger +wastage. There is a slight speed loss here, but it's of doubtful +significance. + + NOTE: Apparently there is a third-generation GNU malloc that is +significantly better than the new GNU malloc, and should probably be +included in XEmacs. + + There is also the relocating allocator, `ralloc.c'. This actually +moves blocks of memory around so that the `sbrk()' pointer shrunk and +virtual memory released back to the system. On some systems, this is a +big win. On all systems, it causes a noticeable (and sometimes huge) +speed penalty, so I turn it off by default. `ralloc.c' only works with +the new GNU malloc in `gmalloc.c'. There are also two versions of +`ralloc.c', one that uses `mmap()' rather than block copies to move +data around. This purports to be faster, although that depends on the +amount of data that would have had to be block copied and the +system-call overhead for `mmap()'. I don't know exactly how this +works, except that the relocating-allocation routines are pretty much +used only for the memory allocated for a buffer, which is the biggest +consumer of space, esp. of space that may get freed later. + + Note that the GNU mallocs have some "memory warning" facilities. +XEmacs taps into them and issues a warning through the standard warning +system, when memory gets to 75%, 85%, and 95% full. (On some systems, +the memory warnings are not functional.) + + Allocated memory that is going to be used to make a Lisp object is +created using `allocate_lisp_storage()'. This just calls `xmalloc()'. +It used to verify that the pointer to the memory can fit into a Lisp +word, before the current Lisp object representation was introduced. +`allocate_lisp_storage()' is called by `alloc_lcrecord()', +`ALLOCATE_FIXED_TYPE()', and the vector and bit-vector creation +routines. These routines also call `INCREMENT_CONS_COUNTER()' at the +appropriate times; this keeps statistics on how much memory is +allocated, so that garbage-collection can be invoked when the threshold +is reached. + + +File: internals.info, Node: Cons, Next: Vector, Prev: Low-level allocation, Up: Allocation of Objects in XEmacs Lisp + +Cons +==== + +Conses are allocated in standard frob blocks. The only thing to note +is that conses can be explicitly freed using `free_cons()' and +associated functions `free_list()' and `free_alist()'. This +immediately puts the conses onto the cons free list, and decrements the +statistics on memory allocation appropriately. This is used to good +effect by some extremely commonly-used code, to avoid generating extra +objects and thereby triggering GC sooner. However, you have to be +_extremely_ careful when doing this. If you mess this up, you will get +BADLY BURNED, and it has happened before. + + +File: internals.info, Node: Vector, Next: Bit Vector, Prev: Cons, Up: Allocation of Objects in XEmacs Lisp + +Vector +====== + +As mentioned above, each vector is `malloc()'ed individually, and all +are threaded through the variable `all_vectors'. Vectors are marked +strangely during garbage collection, by kludging the size field. Note +that the `struct Lisp_Vector' is declared with its `contents' field +being a _stretchy_ array of one element. It is actually `malloc()'ed +with the right size, however, and access to any element through the +`contents' array works fine. + + +File: internals.info, Node: Bit Vector, Next: Symbol, Prev: Vector, Up: Allocation of Objects in XEmacs Lisp + +Bit Vector +========== + +Bit vectors work exactly like vectors, except for more complicated code +to access an individual bit, and except for the fact that bit vectors +are lrecords while vectors are not. (The only difference here is that +there's an lrecord implementation pointer at the beginning and the tag +field in bit vector Lisp words is "lrecord" rather than "vector".) + + +File: internals.info, Node: Symbol, Next: Marker, Prev: Bit Vector, Up: Allocation of Objects in XEmacs Lisp + +Symbol +====== + +Symbols are also allocated in frob blocks. Symbols in the awful +horrible obarray structure are chained through their `next' field. + + Remember that `intern' looks up a symbol in an obarray, creating one +if necessary. + + +File: internals.info, Node: Marker, Next: String, Prev: Symbol, Up: Allocation of Objects in XEmacs Lisp + +Marker +====== + +Markers are allocated in frob blocks, as usual. They are kept in a +buffer unordered, but in a doubly-linked list so that they can easily +be removed. (Formerly this was a singly-linked list, but in some cases +garbage collection took an extraordinarily long time due to the O(N^2) +time required to remove lots of markers from a buffer.) Markers are +removed from a buffer in the finalize stage, in +`ADDITIONAL_FREE_marker()'. + + +File: internals.info, Node: String, Next: Compiled Function, Prev: Marker, Up: Allocation of Objects in XEmacs Lisp + +String +====== + +As mentioned above, strings are a special case. A string is logically +two parts, a fixed-size object (containing the length, property list, +and a pointer to the actual data), and the actual data in the string. +The fixed-size object is a `struct Lisp_String' and is allocated in +frob blocks, as usual. The actual data is stored in special +"string-chars blocks", which are 8K blocks of memory. +Currently-allocated strings are simply laid end to end in these +string-chars blocks, with a pointer back to the `struct Lisp_String' +stored before each string in the string-chars block. When a new string +needs to be allocated, the remaining space at the end of the last +string-chars block is used if there's enough, and a new string-chars +block is created otherwise. + + There are never any holes in the string-chars blocks due to the +string compaction and relocation that happens at the end of garbage +collection. During the sweep stage of garbage collection, when objects +are reclaimed, the garbage collector goes through all string-chars +blocks, looking for unused strings. Each chunk of string data is +preceded by a pointer to the corresponding `struct Lisp_String', which +indicates both whether the string is used and how big the string is, +i.e. how to get to the next chunk of string data. Holes are compressed +by block-copying the next string into the empty space and relocating the +pointer stored in the corresponding `struct Lisp_String'. *This means +you have to be careful with strings in your code.* See the section +above on `GCPRO'ing. + + Note that there is one situation not handled: a string that is too +big to fit into a string-chars block. Such strings, called "big +strings", are all `malloc()'ed as their own block. (#### Although it +would make more sense for the threshold for big strings to be somewhat +lower, e.g. 1/2 or 1/4 the size of a string-chars block. It seems that +this was indeed the case formerly--indeed, the threshold was set at +1/8--but Mly forgot about this when rewriting things for 19.8.) + + Note also that the string data in string-chars blocks is padded as +necessary so that proper alignment constraints on the `struct +Lisp_String' back pointers are maintained. + + Finally, strings can be resized. This happens in Mule when a +character is substituted with a different-length character, or during +modeline frobbing. (You could also export this to Lisp, but it's not +done so currently.) Resizing a string is a potentially tricky process. +If the change is small enough that the padding can absorb it, nothing +other than a simple memory move needs to be done. Keep in mind, +however, that the string can't shrink too much because the offset to the +next string in the string-chars block is computed by looking at the +length and rounding to the nearest multiple of four or eight. If the +string would shrink or expand beyond the correct padding, new string +data needs to be allocated at the end of the last string-chars block and +the data moved appropriately. This leaves some dead string data, which +is marked by putting a special marker of 0xFFFFFFFF in the `struct +Lisp_String' pointer before the data (there's no real `struct +Lisp_String' to point to and relocate), and storing the size of the dead +string data (which would normally be obtained from the now-non-existent +`struct Lisp_String') at the beginning of the dead string data gap. +The string compactor recognizes this special 0xFFFFFFFF marker and +handles it correctly. + + +File: internals.info, Node: Compiled Function, Prev: String, Up: Allocation of Objects in XEmacs Lisp + +Compiled Function +================= + +Not yet documented. + + +File: internals.info, Node: Dumping, Next: Events and the Event Loop, Prev: Allocation of Objects in XEmacs Lisp, Up: Top + +Dumping +******* + +What is dumping and its justification +===================================== + +The C code of XEmacs is just a Lisp engine with a lot of built-in +primitives useful for writing an editor. The editor itself is written +mostly in Lisp, and represents around 100K lines of code. Loading and +executing the initialization of all this code takes a bit a time (five +to ten times the usual startup time of current xemacs) and requires +having all the lisp source files around. Having to reload them each +time the editor is started would not be acceptable. + + The traditional solution to this problem is called dumping: the build +process first creates the lisp engine under the name `temacs', then +runs it until it has finished loading and initializing all the lisp +code, and eventually creates a new executable called `xemacs' including +both the object code in `temacs' and all the contents of the memory +after the initialization. + + This solution, while working, has a huge problem: the creation of the +new executable from the actual contents of memory is an extremely +system-specific process, quite error-prone, and which interferes with a +lot of system libraries (like malloc). It is even getting worse +nowadays with libraries using constructors which are automatically +called when the program is started (even before main()) which tend to +crash when they are called multiple times, once before dumping and once +after (IRIX 6.x libz.so pulls in some C++ image libraries thru +dependencies which have this problem). Writing the dumper is also one +of the most difficult parts of porting XEmacs to a new operating system. +Basically, `dumping' is an operation that is just not officially +supported on many operating systems. + + The aim of the portable dumper is to solve the same problem as the +system-specific dumper, that is to be able to reload quickly, using only +a small number of files, the fully initialized lisp part of the editor, +without any system-specific hacks. + +* Menu: + +* Overview:: +* Data descriptions:: +* Dumping phase:: +* Reloading phase:: +* Remaining issues:: + + +File: internals.info, Node: Overview, Next: Data descriptions, Up: Dumping + +Overview +======== + +The portable dumping system has to: + + 1. At dump time, write all initialized, non-quickly-rebuildable data + to a file [Note: currently named `xemacs.dmp', but the name will + change], along with all informations needed for the reloading. + + 2. When starting xemacs, reload the dump file, relocate it to its new + starting address if needed, and reinitialize all pointers to this + data. Also, rebuild all the quickly rebuildable data. + + +File: internals.info, Node: Data descriptions, Next: Dumping phase, Prev: Overview, Up: Dumping + +Data descriptions +================= + +The more complex task of the dumper is to be able to write lisp objects +(lrecords) and C structs to disk and reload them at a different address, +updating all the pointers they include in the process. This is done by +using external data descriptions that give information about the layout +of the structures in memory. + + The specification of these descriptions is in lrecord.h. A +description of an lrecord is an array of struct lrecord_description. +Each of these structs include a type, an offset in the structure and +some optional parameters depending on the type. For instance, here is +the string description: + + static const struct lrecord_description string_description[] = { + { XD_BYTECOUNT, offsetof (Lisp_String, size) }, + { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) }, + { XD_LISP_OBJECT, offsetof (Lisp_String, plist) }, + { XD_END } + }; + + The first line indicates a member of type Bytecount, which is used by +the next, indirect directive. The second means "there is a pointer to +some opaque data in the field `data'". The length of said data is +given by the expression `XD_INDIRECT(0, 1)', which means "the value in +the 0th line of the description (welcome to C) plus one". The third +line means "there is a Lisp_Object member `plist' in the Lisp_String +structure". `XD_END' then ends the description. + + This gives us all the information we need to move around what is +pointed to by a structure (C or lrecord) and, by transitivity, +everything that it points to. The only missing information for dumping +is the size of the structure. For lrecords, this is part of the +lrecord_implementation, so we don't need to duplicate it. For C +structures we use a struct struct_description, which includes a size +field and a pointer to an associated array of lrecord_description. + + +File: internals.info, Node: Dumping phase, Next: Reloading phase, Prev: Data descriptions, Up: Dumping + +Dumping phase +============= + +Dumping is done by calling the function pdump() (in dumper.c) which is +invoked from Fdump_emacs (in emacs.c). This function performs a number +of tasks. + +* Menu: + +* Object inventory:: +* Address allocation:: +* The header:: +* Data dumping:: +* Pointers dumping:: + + +File: internals.info, Node: Object inventory, Next: Address allocation, Up: Dumping phase + +Object inventory +---------------- + +The first task is to build the list of the objects to dump. This +includes: + + * lisp objects + + * C structures + + We end up with one `pdump_entry_list_elmt' per object group (arrays +of C structs are kept together) which includes a pointer to the first +object of the group, the per-object size and the count of objects in the +group, along with some other information which is initialized later. + + These entries are linked together in `pdump_entry_list' structures +and can be enumerated thru either: + + 1. the `pdump_object_table', an array of `pdump_entry_list', one per + lrecord type, indexed by type number. + + 2. the `pdump_opaque_data_list', used for the opaque data which does + not include pointers, and hence does not need descriptions. + + 3. the `pdump_struct_table', which is a vector of + `struct_description'/`pdump_entry_list' pairs, used for non-opaque + C structures. + + This uses a marking strategy similar to the garbage collector. Some +differences though: + + 1. We do not use the mark bit (which does not exist for C structures + anyway); we use a big hash table instead. + + 2. We do not use the mark function of lrecords but instead rely on the + external descriptions. This happens essentially because we need to + follow pointers to C structures and opaque data in addition to + Lisp_Object members. + + This is done by `pdump_register_object()', which handles Lisp_Object +variables, and `pdump_register_struct()' which handles C structures, +which both delegate the description management to +`pdump_register_sub()'. + + The hash table doubles as a map object to pdump_entry_list_elmt (i.e. +allows us to look up a pdump_entry_list_elmt with the object it points +to). Entries are added with `pdump_add_entry()' and looked up with +`pdump_get_entry()'. There is no need for entry removal. The hash +value is computed quite simply from the object pointer by +`pdump_make_hash()'. + + The roots for the marking are: + + 1. the `staticpro''ed variables (there is a special + `staticpro_nodump()' call for protected variables we do not want + to dump). + + 2. the variables registered via `dump_add_root_object' (`staticpro()' + is equivalent to `staticpro_nodump()' + `dump_add_root_object()'). + + 3. the variables registered via `dump_add_root_struct_ptr', each of + which points to a C structure. + + This does not include the GCPRO'ed variables, the specbinds, the +catchtags, the backlist, the redisplay or the profiling info, since we +do not want to rebuild the actual chain of lisp calls which end up to +the dump-emacs call, only the global variables. + + Weak lists and weak hash tables are dumped as if they were their +non-weak equivalent (without changing their type, of course). This has +not yet been a problem. + + +File: internals.info, Node: Address allocation, Next: The header, Prev: Object inventory, Up: Dumping phase + +Address allocation +------------------ + +The next step is to allocate the offsets of each of the objects in the +final dump file. This is done by `pdump_allocate_offset()' which is +called indirectly by `pdump_scan_by_alignment()'. + + The strategy to deal with alignment problems uses these facts: + + 1. real world alignment requirements are powers of two. + + 2. the C compiler is required to adjust the size of a struct so that + you can have an array of them next to each other. This means you + can have an upper bound of the alignment requirements of a given + structure by looking at which power of two its size is a multiple. + + 3. the non-variant part of variable size lrecords has an alignment + requirement of 4. + + Hence, for each lrecord type, C struct type or opaque data block the +alignment requirement is computed as a power of two, with a minimum of +2^2 for lrecords. `pdump_scan_by_alignment()' then scans all the +`pdump_entry_list_elmt''s, the ones with the highest requirements +first. This ensures the best packing. + + The maximum alignment requirement we take into account is 2^8. + + `pdump_allocate_offset()' only has to do a linear allocation, +starting at offset 256 (this leaves room for the header and keeps the +alignments happy). + + +File: internals.info, Node: The header, Next: Data dumping, Prev: Address allocation, Up: Dumping phase + +The header +---------- + +The next step creates the file and writes a header with a signature and +some random information in it. The `reloc_address' field, which +indicates at which address the file should be loaded if we want to avoid +post-reload relocation, is set to 0. It then seeks to offset 256 (base +offset for the objects). + + +File: internals.info, Node: Data dumping, Next: Pointers dumping, Prev: The header, Up: Dumping phase + +Data dumping +------------ + +The data is dumped in the same order as the addresses were allocated by +`pdump_dump_data()', called from `pdump_scan_by_alignment()'. This +function copies the data to a temporary buffer, relocates all pointers +in the object to the addresses allocated in step Address Allocation, +and writes it to the file. Using the same order means that, if we are +careful with lrecords whose size is not a multiple of 4, we are ensured +that the object is always written at the offset in the file allocated +in step Address Allocation. + + +File: internals.info, Node: Pointers dumping, Prev: Data dumping, Up: Dumping phase + +Pointers dumping +---------------- + +A bunch of tables needed to reassign properly the global pointers are +then written. They are: + + 1. the pdump_root_struct_ptrs dynarr + + 2. the pdump_opaques dynarr + + 3. a vector of all the offsets to the objects in the file that + include a description (for faster relocation at reload time) + + 4. the pdump_root_objects and pdump_weak_object_chains dynarrs. + + For each of the dynarrs we write both the pointer to the variables +and the relocated offset of the object they point to. Since these +variables are global, the pointers are still valid when restarting the +program and are used to regenerate the global pointers. + + The `pdump_weak_object_chains' dynarr is a special case. The +variables it points to are the head of weak linked lists of lisp objects +of the same type. Not all objects of this list are dumped so the +relocated pointer we associate with them points to the first dumped +object of the list, or Qnil if none is available. This is also the +reason why they are not used as roots for the purpose of object +enumeration. + + Some very important information like the `staticpros' and +`lrecord_implementations_table' are handled indirectly using +`dump_add_opaque' or `dump_add_root_struct_ptr'. + + This is the end of the dumping part. + + +File: internals.info, Node: Reloading phase, Next: Remaining issues, Prev: Dumping phase, Up: Dumping + +Reloading phase +=============== + +File loading +------------ + +The file is mmap'ed in memory (which ensures a PAGESIZE alignment, at +least 4096), or if mmap is unavailable or fails, a 256-bytes aligned +malloc is done and the file is loaded. + + Some variables are reinitialized from the values found in the header. + + The difference between the actual loading address and the +reloc_address is computed and will be used for all the relocations. + +Putting back the pdump_opaques +------------------------------ + +The memory contents are restored in the obvious and trivial way. + +Putting back the pdump_root_struct_ptrs +--------------------------------------- + +The variables pointed to by pdump_root_struct_ptrs in the dump phase are +reset to the right relocated object addresses. + +Object relocation +----------------- + +All the objects are relocated using their description and their offset +by `pdump_reloc_one'. This step is unnecessary if the reloc_address is +equal to the file loading address. + +Putting back the pdump_root_objects and pdump_weak_object_chains +---------------------------------------------------------------- + +Same as Putting back the pdump_root_struct_ptrs. + +Reorganize the hash tables +-------------------------- + +Since some of the hash values in the lisp hash tables are +address-dependent, their layout is now wrong. So we go through each of +them and have them resorted by calling `pdump_reorganize_hash_table'. + + +File: internals.info, Node: Remaining issues, Prev: Reloading phase, Up: Dumping + +Remaining issues +================ + +The build process will have to start a post-dump xemacs, ask it the +loading address (which will, hopefully, be always the same between +different xemacs invocations) and relocate the file to the new address. +This way the object relocation phase will not have to be done, which +means no writes in the objects and that, because of the use of mmap, the +dumped data will be shared between all the xemacs running on the +computer. + + Some executable signature will be necessary to ensure that a given +dump file is really associated with a given executable, or random +crashes will occur. Maybe a random number set at compile or configure +time thru a define. This will also allow for having +differently-compiled xemacsen on the same system (mule and no-mule +comes to mind). + + The DOC file contents should probably end up in the dump file. + + +File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Dumping, Up: Top + +Events and the Event Loop +************************* + +* Menu: + +* Introduction to Events:: +* Main Loop:: +* Specifics of the Event Gathering Mechanism:: +* Specifics About the Emacs Event:: +* The Event Stream Callback Routines:: +* Other Event Loop Functions:: +* Converting Events:: +* Dispatching Events; The Command Builder:: + + +File: internals.info, Node: Introduction to Events, Next: Main Loop, Up: Events and the Event Loop + +Introduction to Events +====================== + +An event is an object that encapsulates information about an +interesting occurrence in the operating system. Events are generated +either by user action, direct (e.g. typing on the keyboard or moving +the mouse) or indirect (moving another window, thereby generating an +expose event on an Emacs frame), or as a result of some other typically +asynchronous action happening, such as output from a subprocess being +ready or a timer expiring. Events come into the system in an +asynchronous fashion (typically through a callback being called) and +are converted into a synchronous event queue (first-in, first-out) in a +process that we will call "collection". + + Note that each application has its own event queue. (It is +immaterial whether the collection process directly puts the events in +the proper application's queue, or puts them into a single system +queue, which is later split up.) + + The most basic level of event collection is done by the operating +system or window system. Typically, XEmacs does its own event +collection as well. Often there are multiple layers of collection in +XEmacs, with events from various sources being collected into a queue, +which is then combined with other sources to go into another queue +(i.e. a second level of collection), with perhaps another level on top +of this, etc. + + XEmacs has its own types of events (called "Emacs events"), which +provides an abstract layer on top of the system-dependent nature of the +most basic events that are received. Part of the complex nature of the +XEmacs event collection process involves converting from the +operating-system events into the proper Emacs events--there may not be +a one-to-one correspondence. + + Emacs events are documented in `events.h'; I'll discuss them later. + + +File: internals.info, Node: Main Loop, Next: Specifics of the Event Gathering Mechanism, Prev: Introduction to Events, Up: Events and the Event Loop + +Main Loop +========= + +The "command loop" is the top-level loop that the editor is always +running. It loops endlessly, calling `next-event' to retrieve an event +and `dispatch-event' to execute it. `dispatch-event' does the +appropriate thing with non-user events (process, timeout, magic, eval, +mouse motion); this involves calling a Lisp handler function, redrawing +a newly-exposed part of a frame, reading subprocess output, etc. For +user events, `dispatch-event' looks up the event in relevant keymaps or +menubars; when a full key sequence or menubar selection is reached, the +appropriate function is executed. `dispatch-event' may have to keep +state across calls; this is done in the "command-builder" structure +associated with each console (remember, there's usually only one +console), and the engine that looks up keystrokes and constructs full +key sequences is called the "command builder". This is documented +elsewhere. + + The guts of the command loop are in `command_loop_1()'. This +function doesn't catch errors, though--that's the job of +`command_loop_2()', which is a condition-case (i.e. error-trapping) +wrapper around `command_loop_1()'. `command_loop_1()' never returns, +but may get thrown out of. + + When an error occurs, `cmd_error()' is called, which usually invokes +the Lisp error handler in `command-error'; however, a default error +handler is provided if `command-error' is `nil' (e.g. during startup). +The purpose of the error handler is simply to display the error message +and do associated cleanup; it does not need to throw anywhere. When +the error handler finishes, the condition-case in `command_loop_2()' +will finish and `command_loop_2()' will reinvoke `command_loop_1()'. + + `command_loop_2()' is invoked from three places: from +`initial_command_loop()' (called from `main()' at the end of internal +initialization), from the Lisp function `recursive-edit', and from +`call_command_loop()'. + + `call_command_loop()' is called when a macro is started and when the +minibuffer is entered; normal termination of the macro or minibuffer +causes a throw out of the recursive command loop. (To +`execute-kbd-macro' for macros and `exit' for minibuffers. Note also +that the low-level minibuffer-entering function, +`read-minibuffer-internal', provides its own error handling and does +not need `command_loop_2()''s error encapsulation; so it tells +`call_command_loop()' to invoke `command_loop_1()' directly.) + + Note that both read-minibuffer-internal and recursive-edit set up a +catch for `exit'; this is why `abort-recursive-edit', which throws to +this catch, exits out of either one. + + `initial_command_loop()', called from `main()', sets up a catch for +`top-level' when invoking `command_loop_2()', allowing functions to +throw all the way to the top level if they really need to. Before +invoking `command_loop_2()', `initial_command_loop()' calls +`top_level_1()', which handles all of the startup stuff (creating the +initial frame, handling the command-line options, loading the user's +`.emacs' file, etc.). The function that actually does this is in Lisp +and is pointed to by the variable `top-level'; normally this function is +`normal-top-level'. `top_level_1()' is just an error-handling wrapper +similar to `command_loop_2()'. Note also that `initial_command_loop()' +sets up a catch for `top-level' when invoking `top_level_1()', just +like when it invokes `command_loop_2()'. + + +File: internals.info, Node: Specifics of the Event Gathering Mechanism, Next: Specifics About the Emacs Event, Prev: Main Loop, Up: Events and the Event Loop + +Specifics of the Event Gathering Mechanism +========================================== + +Here is an approximate diagram of the collection processes at work in +XEmacs, under TTY's (TTY's are simpler than X so we'll look at this +first): + + asynch. asynch. asynch. asynch. [Collectors in + kbd events kbd events process process the OS] + | | output output + | | | | + | | | | SIGINT, [signal handlers + | | | | SIGQUIT, in XEmacs] + V V V V SIGWINCH, + file file file file SIGALRM + desc. desc. desc. desc. | + (TTY) (TTY) (pipe) (pipe) | + | | | | fake timeouts + | | | | file | + | | | | desc. | + | | | | (pipe) | + | | | | | | + | | | | | | + | | | | | | + V V V V V V + ------>-----------<----------------<---------------- + | + | + | [collected using select() in emacs_tty_next_event() + | and converted to the appropriate Emacs event] + | + | + V (above this line is TTY-specific) + Emacs ----------------------------------------------- + event (below this line is the generic event mechanism) + | + | + was there if not, call + a SIGINT? emacs_tty_next_event() + | | + | | + | | + V V + --->------<---- + | + | [collected in event_stream_next_event(); + | SIGINT is converted using maybe_read_quit_event()] + V + Emacs + event + | + \---->------>----- maybe_kbd_translate() ---->---\ + | + | + | + command event queue | + if not from command + (contains events that were event queue, call + read earlier but not processed, event_stream_next_event() + typically when waiting in a | + sit-for, sleep-for, etc. for | + a particular event to be received) | + | | + | | + V V + ---->------------------------------------<---- + | + | [collected in + | next_event_internal()] + | + unread- unread- event from | + command- command- keyboard else, call + events event macro next_event_internal() + | | | | + | | | | + | | | | + V V V V + --------->----------------------<------------ + | + | [collected in `next-event', which may loop + | more than once if the event it gets is on + | a dead frame, device, etc.] + | + | + V + feed into top-level event loop, + which repeatedly calls `next-event' + and then dispatches the event + using `dispatch-event' + + Notice the separation between TTY-specific and generic event +mechanism. When using the Xt-based event loop, the TTY-specific stuff +is replaced but the rest stays the same. + + It's also important to realize that only one different kind of +system-specific event loop can be operating at a time, and must be able +to receive all kinds of events simultaneously. For the two existing +event loops (implemented in `event-tty.c' and `event-Xt.c', +respectively), the TTY event loop _only_ handles TTY consoles, while +the Xt event loop handles _both_ TTY and X consoles. This situation is +different from all of the output handlers, where you simply have one +per console type. + + Here's the Xt Event Loop Diagram (notice that below a certain point, +it's the same as the above diagram): + + asynch. asynch. asynch. asynch. [Collectors in + kbd kbd process process the OS] + events events output output + | | | | + | | | | asynch. asynch. [Collectors in the + | | | | X X OS and X Window System] + | | | | events events + | | | | | | + | | | | | | + | | | | | | SIGINT, [signal handlers + | | | | | | SIGQUIT, in XEmacs] + | | | | | | SIGWINCH, + | | | | | | SIGALRM + | | | | | | | + | | | | | | | + | | | | | | | timeouts + | | | | | | | | + | | | | | | | | + | | | | | | V | + V V V V V V fake | + file file file file file file file | + desc. desc. desc. desc. desc. desc. desc. | + (TTY) (TTY) (pipe) (pipe) (socket) (socket) (pipe) | + | | | | | | | | + | | | | | | | | + | | | | | | | | + V V V V V V V V + --->----------------------------------------<---------<------ + | | | + | | |[collected using select() in + | | | _XtWaitForSomething(), called + | | | from XtAppProcessEvent(), called + | | | in emacs_Xt_next_event(); + | | | dispatched to various callbacks] + | | | + | | | + emacs_Xt_ p_s_callback(), | [popup_selection_callback] + event_handler() x_u_v_s_callback(),| [x_update_vertical_scrollbar_ + | x_u_h_s_callback(),| callback] + | search_callback() | [x_update_horizontal_scrollbar_ + | | | callback] + | | | + | | | + enqueue_Xt_ signal_special_ | + dispatch_event() Xt_user_event() | + [maybe multiple | | + times, maybe 0 | | + times] | | + | enqueue_Xt_ | + | dispatch_event() | + | | | + | | | + V V | + -->----------<-- | + | | + | | + dispatch Xt_what_callback() + event sets flags + queue | + | | + | | + | | + | | + ---->-----------<-------- + | + | + | [collected and converted as appropriate in + | emacs_Xt_next_event()] + | + | + V (above this line is Xt-specific) + Emacs ------------------------------------------------ + event (below this line is the generic event mechanism) + | + | + was there if not, call + a SIGINT? emacs_Xt_next_event() + | | + | | + | | + V V + --->-------<---- + | + | [collected in event_stream_next_event(); + | SIGINT is converted using maybe_read_quit_event()] + V + Emacs + event + | + \---->------>----- maybe_kbd_translate() -->-----\ + | + | + | + command event queue | + if not from command + (contains events that were event queue, call + read earlier but not processed, event_stream_next_event() + typically when waiting in a | + sit-for, sleep-for, etc. for | + a particular event to be received) | + | | + | | + V V + ---->----------------------------------<------ + | + | [collected in + | next_event_internal()] + | + unread- unread- event from | + command- command- keyboard else, call + events event macro next_event_internal() + | | | | + | | | | + | | | | + V V V V + --------->----------------------<------------ + | + | [collected in `next-event', which may loop + | more than once if the event it gets is on + | a dead frame, device, etc.] + | + | + V + feed into top-level event loop, + which repeatedly calls `next-event' + and then dispatches the event + using `dispatch-event' + + +File: internals.info, Node: Specifics About the Emacs Event, Next: The Event Stream Callback Routines, Prev: Specifics of the Event Gathering Mechanism, Up: Events and the Event Loop + +Specifics About the Emacs Event +=============================== + + +File: internals.info, Node: The Event Stream Callback Routines, Next: Other Event Loop Functions, Prev: Specifics About the Emacs Event, Up: Events and the Event Loop + +The Event Stream Callback Routines +================================== + + +File: internals.info, Node: Other Event Loop Functions, Next: Converting Events, Prev: The Event Stream Callback Routines, Up: Events and the Event Loop + +Other Event Loop Functions +========================== + +`detect_input_pending()' and `input-pending-p' look for input by +calling `event_stream->event_pending_p' and looking in +`[V]unread-command-event' and the `command_event_queue' (they do not +check for an executing keyboard macro, though). + + `discard-input' cancels any command events pending (and any keyboard +macros currently executing), and puts the others onto the +`command_event_queue'. There is a comment about a "race condition", +which is not a good sign. + + `next-command-event' and `read-char' are higher-level interfaces to +`next-event'. `next-command-event' gets the next "command" event (i.e. +keypress, mouse event, menu selection, or scrollbar action), calling +`dispatch-event' on any others. `read-char' calls `next-command-event' +and uses `event_to_character()' to return the character equivalent. +With the right kind of input method support, it is possible for +(read-char) to return a Kanji character. + + +File: internals.info, Node: Converting Events, Next: Dispatching Events; The Command Builder, Prev: Other Event Loop Functions, Up: Events and the Event Loop + +Converting Events +================= + +`character_to_event()', `event_to_character()', `event-to-character', +and `character-to-event' convert between characters and keypress events +corresponding to the characters. If the event was not a keypress, +`event_to_character()' returns -1 and `event-to-character' returns +`nil'. These functions convert between character representation and +the split-up event representation (keysym plus mod keys). + + +File: internals.info, Node: Dispatching Events; The Command Builder, Prev: Converting Events, Up: Events and the Event Loop + +Dispatching Events; The Command Builder +======================================= + +Not yet documented. + + +File: internals.info, Node: Evaluation; Stack Frames; Bindings, Next: Symbols and Variables, Prev: Events and the Event Loop, Up: Top + +Evaluation; Stack Frames; Bindings +********************************** + +* Menu: + +* Evaluation:: +* Dynamic Binding; The specbinding Stack; Unwind-Protects:: +* Simple Special Forms:: +* Catch and Throw:: + + +File: internals.info, Node: Evaluation, Next: Dynamic Binding; The specbinding Stack; Unwind-Protects, Up: Evaluation; Stack Frames; Bindings + +Evaluation +========== + +`Feval()' evaluates the form (a Lisp object) that is passed to it. +Note that evaluation is only non-trivial for two types of objects: +symbols and conses. A symbol is evaluated simply by calling +`symbol-value' on it and returning the value. + + Evaluating a cons means calling a function. First, `eval' checks to +see if garbage-collection is necessary, and calls `garbage_collect_1()' +if so. It then increases the evaluation depth by 1 (`lisp_eval_depth', +which is always less than `max_lisp_eval_depth') and adds an element to +the linked list of `struct backtrace''s (`backtrace_list'). Each such +structure contains a pointer to the function being called plus a list +of the function's arguments. Originally these values are stored +unevalled, and as they are evaluated, the backtrace structure is +updated. Garbage collection pays attention to the objects pointed to +in the backtrace structures (garbage collection might happen while a +function is being called or while an argument is being evaluated, and +there could easily be no other references to the arguments in the +argument list; once an argument is evaluated, however, the unevalled +version is not needed by eval, and so the backtrace structure is +changed). + + At this point, the function to be called is determined by looking at +the car of the cons (if this is a symbol, its function definition is +retrieved and the process repeated). The function should then consist +of either a `Lisp_Subr' (built-in function written in C), a +`Lisp_Compiled_Function' object, or a cons whose car is one of the +symbols `autoload', `macro' or `lambda'. + + If the function is a `Lisp_Subr', the lisp object points to a +`struct Lisp_Subr' (created by `DEFUN()'), which contains a pointer to +the C function, a minimum and maximum number of arguments (or possibly +the special constants `MANY' or `UNEVALLED'), a pointer to the symbol +referring to that subr, and a couple of other things. If the subr +wants its arguments `UNEVALLED', they are passed raw as a list. +Otherwise, an array of evaluated arguments is created and put into the +backtrace structure, and either passed whole (`MANY') or each argument +is passed as a C argument. + + If the function is a `Lisp_Compiled_Function', +`funcall_compiled_function()' is called. If the function is a lambda +list, `funcall_lambda()' is called. If the function is a macro, [..... +fill in] is done. If the function is an autoload, `do_autoload()' is +called to load the definition and then eval starts over [explain this +more]. + + When `Feval()' exits, the evaluation depth is reduced by one, the +debugger is called if appropriate, and the current backtrace structure +is removed from the list. + + Both `funcall_compiled_function()' and `funcall_lambda()' need to go +through the list of formal parameters to the function and bind them to +the actual arguments, checking for `&rest' and `&optional' symbols in +the formal parameters and making sure the number of actual arguments is +correct. `funcall_compiled_function()' can do this a little more +efficiently, since the formal parameter list can be checked for sanity +when the compiled function object is created. + + `funcall_lambda()' simply calls `Fprogn' to execute the code in the +lambda list. + + `funcall_compiled_function()' calls the real byte-code interpreter +`execute_optimized_program()' on the byte-code instructions, which are +converted into an internal form for faster execution. + + When a compiled function is executed for the first time by +`funcall_compiled_function()', or during the dump phase of building +XEmacs, the byte-code instructions are converted from a `Lisp_String' +(which is inefficient to access, especially in the presence of MULE) +into a `Lisp_Opaque' object containing an array of unsigned char, which +can be directly executed by the byte-code interpreter. At this time +the byte code is also analyzed for validity and transformed into a more +optimized form, so that `execute_optimized_program()' can really fly. + + Here are some of the optimizations performed by the internal +byte-code transformer: + 1. References to the `constants' array are checked for out-of-range + indices, so that the byte interpreter doesn't have to. + + 2. References to the `constants' array that will be used as a Lisp + variable are checked for being correct non-constant (i.e. not `t', + `nil', or `keywordp') symbols, so that the byte interpreter + doesn't have to. + + 3. The maximum number of variable bindings in the byte-code is + pre-computed, so that space on the `specpdl' stack can be + pre-reserved once for the whole function execution. + + 4. All byte-code jumps are relative to the current program counter + instead of the start of the program, thereby saving a register. + + 5. One-byte relative jumps are converted from the byte-code form of + unsigned chars offset by 127 to machine-friendly signed chars. + + Of course, this transformation of the `instructions' should not be +visible to the user, so `Fcompiled_function_instructions()' needs to +know how to convert the optimized opaque object back into a Lisp string +that is identical to the original string from the `.elc' file. +(Actually, the resulting string may (rarely) contain slightly +different, yet equivalent, byte code.) + + `Ffuncall()' implements Lisp `funcall'. `(funcall fun x1 x2 x3 +...)' is equivalent to `(eval (list fun (quote x1) (quote x2) (quote +x3) ...))'. `Ffuncall()' contains its own code to do the evaluation, +however, and is very similar to `Feval()'. + + From the performance point of view, it is worth knowing that most of +the time in Lisp evaluation is spent executing `Lisp_Subr' and +`Lisp_Compiled_Function' objects via `Ffuncall()' (not `Feval()'). + + `Fapply()' implements Lisp `apply', which is very similar to +`funcall' except that if the last argument is a list, the result is the +same as if each of the arguments in the list had been passed separately. +`Fapply()' does some business to expand the last argument if it's a +list, then calls `Ffuncall()' to do the work. + + `apply1()', `call0()', `call1()', `call2()', and `call3()' call a +function, passing it the argument(s) given (the arguments are given as +separate C arguments rather than being passed as an array). `apply1()' +uses `Fapply()' while the others use `Ffuncall()' to do the real work. + + +File: internals.info, Node: Dynamic Binding; The specbinding Stack; Unwind-Protects, Next: Simple Special Forms, Prev: Evaluation, Up: Evaluation; Stack Frames; Bindings + +Dynamic Binding; The specbinding Stack; Unwind-Protects +======================================================= + + struct specbinding + { + Lisp_Object symbol; + Lisp_Object old_value; + Lisp_Object (*func) (Lisp_Object); /* for unwind-protect */ + }; + + `struct specbinding' is used for local-variable bindings and +unwind-protects. `specpdl' holds an array of `struct specbinding''s, +`specpdl_ptr' points to the beginning of the free bindings in the +array, `specpdl_size' specifies the total number of binding slots in +the array, and `max_specpdl_size' specifies the maximum number of +bindings the array can be expanded to hold. `grow_specpdl()' increases +the size of the `specpdl' array, multiplying its size by 2 but never +exceeding `max_specpdl_size' (except that if this number is less than +400, it is first set to 400). + + `specbind()' binds a symbol to a value and is used for local +variables and `let' forms. The symbol and its old value (which might +be `Qunbound', indicating no prior value) are recorded in the specpdl +array, and `specpdl_size' is increased by 1. + + `record_unwind_protect()' implements an "unwind-protect", which, +when placed around a section of code, ensures that some specified +cleanup routine will be executed even if the code exits abnormally +(e.g. through a `throw' or quit). `record_unwind_protect()' simply +adds a new specbinding to the `specpdl' array and stores the +appropriate information in it. The cleanup routine can either be a C +function, which is stored in the `func' field, or a `progn' form, which +is stored in the `old_value' field. + + `unbind_to()' removes specbindings from the `specpdl' array until +the specified position is reached. Each specbinding can be one of +three types: + + 1. an unwind-protect with a C cleanup function (`func' is not 0, and + `old_value' holds an argument to be passed to the function); + + 2. an unwind-protect with a Lisp form (`func' is 0, `symbol' is + `nil', and `old_value' holds the form to be executed with + `Fprogn()'); or + + 3. a local-variable binding (`func' is 0, `symbol' is not `nil', and + `old_value' holds the old value, which is stored as the symbol's + value). + + +File: internals.info, Node: Simple Special Forms, Next: Catch and Throw, Prev: Dynamic Binding; The specbinding Stack; Unwind-Protects, Up: Evaluation; Stack Frames; Bindings + +Simple Special Forms +==================== + +`or', `and', `if', `cond', `progn', `prog1', `prog2', `setq', `quote', +`function', `let*', `let', `while' + + All of these are very simple and work as expected, calling `Feval()' +or `Fprogn()' as necessary and (in the case of `let' and `let*') using +`specbind()' to create bindings and `unbind_to()' to undo the bindings +when finished. + + Note that, with the exception of `Fprogn', these functions are +typically called in real life only in interpreted code, since the byte +compiler knows how to convert calls to these functions directly into +byte code. + + +File: internals.info, Node: Catch and Throw, Prev: Simple Special Forms, Up: Evaluation; Stack Frames; Bindings + +Catch and Throw +=============== + + struct catchtag + { + Lisp_Object tag; + Lisp_Object val; + struct catchtag *next; + struct gcpro *gcpro; + jmp_buf jmp; + struct backtrace *backlist; + int lisp_eval_depth; + int pdlcount; + }; + + `catch' is a Lisp function that places a catch around a body of +code. A catch is a means of non-local exit from the code. When a catch +is created, a tag is specified, and executing a `throw' to this tag +will exit from the body of code caught with this tag, and its value will +be the value given in the call to `throw'. If there is no such call, +the code will be executed normally. + + Information pertaining to a catch is held in a `struct catchtag', +which is placed at the head of a linked list pointed to by `catchlist'. +`internal_catch()' is passed a C function to call (`Fprogn()' when +Lisp `catch' is called) and arguments to give it, and places a catch +around the function. Each `struct catchtag' is held in the stack frame +of the `internal_catch()' instance that created the catch. + + `internal_catch()' is fairly straightforward. It stores into the +`struct catchtag' the tag name and the current values of +`backtrace_list', `lisp_eval_depth', `gcprolist', and the offset into +the `specpdl' array, sets a jump point with `_setjmp()' (storing the +jump point into the `struct catchtag'), and calls the function. +Control will return to `internal_catch()' either when the function +exits normally or through a `_longjmp()' to this jump point. In the +latter case, `throw' will store the value to be returned into the +`struct catchtag' before jumping. When it's done, `internal_catch()' +removes the `struct catchtag' from the catchlist and returns the proper +value. + + `Fthrow()' goes up through the catchlist until it finds one with a +matching tag. It then calls `unbind_catch()' to restore everything to +what it was when the appropriate catch was set, stores the return value +in the `struct catchtag', and jumps (with `_longjmp()') to its jump +point. + + `unbind_catch()' removes all catches from the catchlist until it +finds the correct one. Some of the catches might have been placed for +error-trapping, and if so, the appropriate entries on the handlerlist +must be removed (see "errors"). `unbind_catch()' also restores the +values of `gcprolist', `backtrace_list', and `lisp_eval', and calls +`unbind_to()' to undo any specbindings created since the catch. + + +File: internals.info, Node: Symbols and Variables, Next: Buffers and Textual Representation, Prev: Evaluation; Stack Frames; Bindings, Up: Top + +Symbols and Variables +********************* + +* Menu: + +* Introduction to Symbols:: +* Obarrays:: +* Symbol Values:: + diff -u -r -N xemacs-21.4.14/info/internals.info-2 xemacs-21.4.15/info/internals.info-2 --- xemacs-21.4.14/info/internals.info-2 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-2 2004-02-02 22:01:07.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from +This is ../info/internals.info, produced by makeinfo version 4.6 from internals/internals.texi. INFO-DIR-SECTION XEmacs Editor @@ -7,8 +7,9 @@ END-INFO-DIR-ENTRY Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. +Microsystems. Copyright (C) 1994 - 1998, 2002, 2003 Free Software +Foundation. Copyright (C) 1994, 1995 Board of Trustees, University of +Illinois. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -38,1009 +39,2819 @@ Foundation instead of in the original English.  -File: internals.info, Node: The XEmacs Object System (Abstractly Speaking), Next: How Lisp Objects Are Represented in C, Prev: XEmacs From the Inside, Up: Top +File: internals.info, Node: Introduction to Symbols, Next: Obarrays, Up: Symbols and Variables -The XEmacs Object System (Abstractly Speaking) -********************************************** +Introduction to Symbols +======================= - At the heart of the Lisp interpreter is its management of objects. -XEmacs Lisp contains many built-in objects, some of which are simple -and others of which can be very complex; and some of which are very -common, and others of which are rarely used or are only used -internally. (Since the Lisp allocation system, with its automatic -reclamation of unused storage, is so much more convenient than -`malloc()' and `free()', the C code makes extensive use of it in its -internal operations.) - - The basic Lisp objects are - -`integer' - 28 or 31 bits of precision, or 60 or 63 bits on 64-bit machines; - the reason for this is described below when the internal Lisp - object representation is described. - -`float' - Same precision as a double in C. - -`cons' - A simple container for two Lisp objects, used to implement lists - and most other data structures in Lisp. - -`char' - An object representing a single character of text; chars behave - like integers in many ways but are logically considered text - rather than numbers and have a different read syntax. (the read - syntax for a char contains the char itself or some textual - encoding of it--for example, a Japanese Kanji character might be - encoded as `^[$(B#&^[(B' using the ISO-2022 encoding - standard--rather than the numerical representation of the char; - this way, if the mapping between chars and integers changes, which - is quite possible for Kanji characters and other extended - characters, the same character will still be created. Note that - some primitives confuse chars and integers. The worst culprit is - `eq', which makes a special exception and considers a char to be - `eq' to its integer equivalent, even though in no other case are - objects of two different types `eq'. The reason for this - monstrosity is compatibility with existing code; the separation of - char from integer came fairly recently.) - -`symbol' - An object that contains Lisp objects and is referred to by name; - symbols are used to implement variables and named functions and to - provide the equivalent of preprocessor constants in C. - -`vector' - A one-dimensional array of Lisp objects providing constant-time - access to any of the objects; access to an arbitrary object in a - vector is faster than for lists, but the operations that can be - done on a vector are more limited. - -`string' - Self-explanatory; behaves much like a vector of chars but has a - different read syntax and is stored and manipulated more compactly. - -`bit-vector' - A vector of bits; similar to a string in spirit. - -`compiled-function' - An object containing compiled Lisp code, known as "byte code". - -`subr' - A Lisp primitive, i.e. a Lisp-callable function implemented in C. - - Note that there is no basic "function" type, as in more powerful -versions of Lisp (where it's called a "closure"). XEmacs Lisp does not -provide the closure semantics implemented by Common Lisp and Scheme. -The guts of a function in XEmacs Lisp are represented in one of four -ways: a symbol specifying another function (when one function is an -alias for another), a list (whose first element must be the symbol -`lambda') containing the function's source code, a compiled-function -object, or a subr object. (In other words, given a symbol specifying -the name of a function, calling `symbol-function' to retrieve the -contents of the symbol's function cell will return one of these types -of objects.) +A symbol is basically just an object with four fields: a name (a +string), a value (some Lisp object), a function (some Lisp object), and +a property list (usually a list of alternating keyword/value pairs). +What makes symbols special is that there is usually only one symbol with +a given name, and the symbol is referred to by name. This makes a +symbol a convenient way of calling up data by name, i.e. of implementing +variables. (The variable's value is stored in the "value slot".) +Similarly, functions are referenced by name, and the definition of the +function is stored in a symbol's "function slot". This means that +there can be a distinct function and variable with the same name. The +property list is used as a more general mechanism of associating +additional values with particular names, and once again the namespace is +independent of the function and variable namespaces. - XEmacs Lisp also contains numerous specialized objects used to -implement the editor: + +File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables -`buffer' - Stores text like a string, but is optimized for insertion and - deletion and has certain other properties that can be set. +Obarrays +======== -`frame' - An object with various properties whose displayable representation - is a "window" in window-system parlance. +The identity of symbols with their names is accomplished through a +structure called an obarray, which is just a poorly-implemented hash +table mapping from strings to symbols whose name is that string. (I say +"poorly implemented" because an obarray appears in Lisp as a vector +with some hidden fields rather than as its own opaque type. This is an +Emacs Lisp artifact that should be fixed.) + + Obarrays are implemented as a vector of some fixed size (which should +be a prime for best results), where each "bucket" of the vector +contains one or more symbols, threaded through a hidden `next' field in +the symbol. Lookup of a symbol in an obarray, and adding a symbol to +an obarray, is accomplished through standard hash-table techniques. + + The standard Lisp function for working with symbols and obarrays is +`intern'. This looks up a symbol in an obarray given its name; if it's +not found, a new symbol is automatically created with the specified +name, added to the obarray, and returned. This is what happens when the +Lisp reader encounters a symbol (or more precisely, encounters the name +of a symbol) in some text that it is reading. There is a standard +obarray called `obarray' that is used for this purpose, although the +Lisp programmer is free to create his own obarrays and `intern' symbols +in them. + + Note that, once a symbol is in an obarray, it stays there until +something is done about it, and the standard obarray `obarray' always +stays around, so once you use any particular variable name, a +corresponding symbol will stay around in `obarray' until you exit +XEmacs. + + Note that `obarray' itself is a variable, and as such there is a +symbol in `obarray' whose name is `"obarray"' and which contains +`obarray' as its value. + + Note also that this call to `intern' occurs only when in the Lisp +reader, not when the code is executed (at which point the symbol is +already around, stored as such in the definition of the function). + + You can create your own obarray using `make-vector' (this is +horrible but is an artifact) and intern symbols into that obarray. +Doing that will result in two or more symbols with the same name. +However, at most one of these symbols is in the standard `obarray': You +cannot have two symbols of the same name in any particular obarray. +Note that you cannot add a symbol to an obarray in any fashion other +than using `intern': i.e. you can't take an existing symbol and put it +in an existing obarray. Nor can you change the name of an existing +symbol. (Since obarrays are vectors, you can violate the consistency of +things by storing directly into the vector, but let's ignore that +possibility.) + + Usually symbols are created by `intern', but if you really want, you +can explicitly create a symbol using `make-symbol', giving it some +name. The resulting symbol is not in any obarray (i.e. it is +"uninterned"), and you can't add it to any obarray. Therefore its +primary purpose is as a symbol to use in macros to avoid namespace +pollution. It can also be used as a carrier of information, but cons +cells could probably be used just as well. + + You can also use `intern-soft' to look up a symbol but not create a +new one, and `unintern' to remove a symbol from an obarray. This +returns the removed symbol. (Remember: You can't put the symbol back +into any obarray.) Finally, `mapatoms' maps over all of the symbols in +an obarray. + + +File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables + +Symbol Values +============= + +The value field of a symbol normally contains a Lisp object. However, +a symbol can be "unbound", meaning that it logically has no value. +This is internally indicated by storing a special Lisp object, called +"the unbound marker" and stored in the global variable `Qunbound'. The +unbound marker is of a special Lisp object type called +"symbol-value-magic". It is impossible for the Lisp programmer to +directly create or access any object of this type. + + *You must not let any "symbol-value-magic" object escape to the Lisp +level.* Printing any of these objects will cause the message `INTERNAL +EMACS BUG' to appear as part of the print representation. (You may see +this normally when you call `debug_print()' from the debugger on a Lisp +object.) If you let one of these objects escape to the Lisp level, you +will violate a number of assumptions contained in the C code and make +the unbound marker not function right. + + When a symbol is created, its value field (and function field) are +set to `Qunbound'. The Lisp programmer can restore these conditions +later using `makunbound' or `fmakunbound', and can query to see whether +the value of function fields are "bound" (i.e. have a value other than +`Qunbound') using `boundp' and `fboundp'. The fields are set to a +normal Lisp object using `set' (or `setq') and `fset'. + + Other symbol-value-magic objects are used as special markers to +indicate variables that have non-normal properties. This includes any +variables that are tied into C variables (setting the variable magically +sets some global variable in the C code, and likewise for retrieving the +variable's value), variables that magically tie into slots in the +current buffer, variables that are buffer-local, etc. The +symbol-value-magic object is stored in the value cell in place of a +normal object, and the code to retrieve a symbol's value (i.e. +`symbol-value') knows how to do special things with them. This means +that you should not just fetch the value cell directly if you want a +symbol's value. + + The exact workings of this are rather complex and involved and are +well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'. + + +File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top -`window' - A section of a frame that displays the contents of a buffer; often - called a "pane" in window-system parlance. - -`window-configuration' - An object that represents a saved configuration of windows in a - frame. - -`device' - An object representing a screen on which frames can be displayed; - equivalent to a "display" in the X Window System and a "TTY" in - character mode. - -`face' - An object specifying the appearance of text or graphics; it has - properties such as font, foreground color, and background color. - -`marker' - An object that refers to a particular position in a buffer and - moves around as text is inserted and deleted to stay in the same - relative position to the text around it. - -`extent' - Similar to a marker but covers a range of text in a buffer; can - also specify properties of the text, such as a face in which the - text is to be displayed, whether the text is invisible or - unmodifiable, etc. - -`event' - Generated by calling `next-event' and contains information - describing a particular event happening in the system, such as the - user pressing a key or a process terminating. - -`keymap' - An object that maps from events (described using lists, vectors, - and symbols rather than with an event object because the mapping - is for classes of events, rather than individual events) to - functions to execute or other events to recursively look up; the - functions are described by name, using a symbol, or using lists to - specify the function's code. - -`glyph' - An object that describes the appearance of an image (e.g. pixmap) - on the screen; glyphs can be attached to the beginning or end of - extents and in some future version of XEmacs will be able to be - inserted directly into a buffer. - -`process' - An object that describes a connection to an externally-running - process. - - There are some other, less-commonly-encountered general objects: - -`hash-table' - An object that maps from an arbitrary Lisp object to another - arbitrary Lisp object, using hashing for fast lookup. - -`obarray' - A limited form of hash-table that maps from strings to symbols; - obarrays are used to look up a symbol given its name and are not - actually their own object type but are kludgily represented using - vectors with hidden fields (this representation derives from GNU - Emacs). - -`specifier' - A complex object used to specify the value of a display property; a - default value is given and different values can be specified for - particular frames, buffers, windows, devices, or classes of device. - -`char-table' - An object that maps from chars or classes of chars to arbitrary - Lisp objects; internally char tables use a complex nested-vector - representation that is optimized to the way characters are - represented as integers. - -`range-table' - An object that maps from ranges of integers to arbitrary Lisp - objects. - - And some strange special-purpose objects: - -`charset' -`coding-system' - Objects used when MULE, or multi-lingual/Asian-language, support is - enabled. - -`color-instance' -`font-instance' -`image-instance' - An object that encapsulates a window-system resource; instances are - mostly used internally but are exposed on the Lisp level for - cleanness of the specifier model and because it's occasionally - useful for Lisp program to create or query the properties of - instances. - -`subwindow' - An object that encapsulate a "subwindow" resource, i.e. a - window-system child window that is drawn into by an external - process; this object should be integrated into the glyph system - but isn't yet, and may change form when this is done. - -`tooltalk-message' -`tooltalk-pattern' - Objects that represent resources used in the ToolTalk interprocess - communication protocol. - -`toolbar-button' - An object used in conjunction with the toolbar. - - And objects that are only used internally: - -`opaque' - A generic object for encapsulating arbitrary memory; this allows - you the generality of `malloc()' and the convenience of the Lisp - object system. - -`lstream' - A buffering I/O stream, used to provide a unified interface to - anything that can accept output or provide input, such as a file - descriptor, a stdio stream, a chunk of memory, a Lisp buffer, a - Lisp string, etc.; it's a Lisp object to make its memory - management more convenient. - -`char-table-entry' - Subsidiary objects in the internal char-table representation. - -`extent-auxiliary' -`menubar-data' -`toolbar-data' - Various special-purpose objects that are basically just used to - encapsulate memory for particular subsystems, similar to the more - general "opaque" object. - -`symbol-value-forward' -`symbol-value-buffer-local' -`symbol-value-varalias' -`symbol-value-lisp-magic' - Special internal-only objects that are placed in the value cell of - a symbol to indicate that there is something special with this - variable - e.g. it has no value, it mirrors another variable, or - it mirrors some C variable; there is really only one kind of - object, called a "symbol-value-magic", but it is sort-of halfway - kludged into semi-different object types. - - Some types of objects are "permanent", meaning that once created, -they do not disappear until explicitly destroyed, using a function such -as `delete-buffer', `delete-window', `delete-frame', etc. Others will -disappear once they are not longer used, through the garbage collection -mechanism. Buffers, frames, windows, devices, and processes are among -the objects that are permanent. Note that some objects can go both -ways: Faces can be created either way; extents are normally permanent, -but detached extents (extents not referring to any text, as happens to -some extents when the text they are referring to is deleted) are -temporary. Note that some permanent objects, such as faces and coding -systems, cannot be deleted. Note also that windows are unique in that -they can be _undeleted_ after having previously been deleted. (This -happens as a result of restoring a window configuration.) - - Note that many types of objects have a "read syntax", i.e. a way of -specifying an object of that type in Lisp code. When you load a Lisp -file, or type in code to be evaluated, what really happens is that the -function `read' is called, which reads some text and creates an object -based on the syntax of that text; then `eval' is called, which possibly -does something special; then this loop repeats until there's no more -text to read. (`eval' only actually does something special with -symbols, which causes the symbol's value to be returned, similar to -referencing a variable; and with conses [i.e. lists], which cause a -function invocation. All other values are returned unchanged.) - - The read syntax - - 17297 - - converts to an integer whose value is 17297. - - 1.983e-4 - - converts to a float whose value is 1.983e-4, or .0001983. - - ?b - - converts to a char that represents the lowercase letter b. - - ?^[$(B#&^[(B - - (where `^[' actually is an `ESC' character) converts to a particular -Kanji character when using an ISO2022-based coding system for input. -(To decode this goo: `ESC' begins an escape sequence; `ESC $ (' is a -class of escape sequences meaning "switch to a 94x94 character set"; -`ESC $ ( B' means "switch to Japanese Kanji"; `#' and `&' collectively -index into a 94-by-94 array of characters [subtract 33 from the ASCII -value of each character to get the corresponding index]; `ESC (' is a -class of escape sequences meaning "switch to a 94 character set"; `ESC -(B' means "switch to US ASCII". It is a coincidence that the letter -`B' is used to denote both Japanese Kanji and US ASCII. If the first -`B' were replaced with an `A', you'd be requesting a Chinese Hanzi -character from the GB2312 character set.) - - "foobar" - - converts to a string. - - foobar - - converts to a symbol whose name is `"foobar"'. This is done by -looking up the string equivalent in the global variable `obarray', -whose contents should be an obarray. If no symbol is found, a new -symbol with the name `"foobar"' is automatically created and added to -`obarray'; this process is called "interning" the symbol. - - (foo . bar) - - converts to a cons cell containing the symbols `foo' and `bar'. - - (1 a 2.5) - - converts to a three-element list containing the specified objects -(note that a list is actually a set of nested conses; see the XEmacs -Lisp Reference). - - [1 a 2.5] - - converts to a three-element vector containing the specified objects. - - #[... ... ... ...] - - converts to a compiled-function object (the actual contents are not -shown since they are not relevant here; look at a file that ends with -`.elc' for examples). - - #*01110110 - - converts to a bit-vector. - - #s(hash-table ... ...) - - converts to a hash table (the actual contents are not shown). - - #s(range-table ... ...) - - converts to a range table (the actual contents are not shown). - - #s(char-table ... ...) - - converts to a char table (the actual contents are not shown). - - Note that the `#s()' syntax is the general syntax for structures, -which are not really implemented in XEmacs Lisp but should be. - - When an object is printed out (using `print' or a related function), -the read syntax is used, so that the same object can be read in again. - - The other objects do not have read syntaxes, usually because it does -not really make sense to create them in this fashion (i.e. processes, -where it doesn't make sense to have a subprocess created as a side -effect of reading some Lisp code), or because they can't be created at -all (e.g. subrs). Permanent objects, as a rule, do not have a read -syntax; nor do most complex objects, which contain too much state to be -easily initialized through a read syntax. - - -File: internals.info, Node: How Lisp Objects Are Represented in C, Next: Rules When Writing New C Code, Prev: The XEmacs Object System (Abstractly Speaking), Up: Top - -How Lisp Objects Are Represented in C -************************************* - - Lisp objects are represented in C using a 32-bit or 64-bit machine -word (depending on the processor; i.e. DEC Alphas use 64-bit Lisp -objects and most other processors use 32-bit Lisp objects). The -representation stuffs a pointer together with a tag, as follows: - - [ 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ] - [ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ] - - <---------------------------------------------------------> <-> - a pointer to a structure, or an integer tag - - A tag of 00 is used for all pointer object types, a tag of 10 is used -for characters, and the other two tags 01 and 11 are joined together to -form the integer object type. This representation gives us 31 bit -integers and 30 bit characters, while pointers are represented directly -without any bit masking or shifting. This representation, though, -assumes that pointers to structs are always aligned to multiples of 4, -so the lower 2 bits are always zero. - - Lisp objects use the typedef `Lisp_Object', but the actual C type -used for the Lisp object can vary. It can be either a simple type -(`long' on the DEC Alpha, `int' on other machines) or a structure whose -fields are bit fields that line up properly (actually, a union of -structures is used). The choice of which type to use is determined by -the preprocessor constant `USE_UNION_TYPE' which is defined via the -`--use-union-type' option to `configure'. - - Generally the simple integral type is preferable because it ensures -that the compiler will actually use a machine word to represent the -object (some compilers will use more general and less efficient code -for unions and structs even if they can fit in a machine word). The -union type, however, has the advantage of stricter _static_ type -checking. Places where a `Lisp_Object' is mistakenly passed to a -routine expecting an `int' (or vice-versa), or a check is written `if -(foo)' (instead of `if (!NILP (foo))', will be flagged as errors. None -of these lead to the expected results! `Qnil' is not represented as 0 -(so `if (foo)' will *ALWAYS* be true for a `Lisp_Object'), and the -representation of an integer as a `Lisp_Object' is not just the -integer's numeric value, but usually 2x the integer +/- 1.) - - There used to be a claim that the union type simplified debugging. -There may have been a grain of truth to this pre-19.8, when there was no -`lrecord' type and all objects had a separate type appearing in the -tag. Nowadays, however, there is no debugging gain, and in fact -frequent debugging *_loss_*, since many debuggers don't handle unions -very well, and usually there is no way to directly specify a union from -a debugging prompt. - - Furthermore, release builds should *_not_* be done with union type -because (a) you may get less efficiency, with compilers that can't -figure out how to optimize the union into a machine word; (b) even -worse, the union type often triggers miscompilation, especially when -combined with Mule and error-checking. This has been the case at -various times when using GCC and MS VC, at least with `--pdump'. -Therefore, be warned! - - As of 2002 4Q, miscompilation is known to happen with current -versions of *Microsoft VC++* and *GCC in combination with Mule, pdump, -and KKCC* (no error checking). - - Various macros are used to convert between Lisp_Objects and the -corresponding C type. Macros of the form `XINT()', `XCHAR()', -`XSTRING()', `XSYMBOL()', do any required bit shifting and/or masking -and cast it to the appropriate type. `XINT()' needs to be a bit tricky -so that negative numbers are properly sign-extended. Since integers -are stored left-shifted, if the right-shift operator does an arithmetic -shift (i.e. it leaves the most-significant bit as-is rather than -shifting in a zero, so that it mimics a divide-by-two even for negative -numbers) the shift to remove the tag bit is enough. This is the case -on all the systems we support. - - Note that when `ERROR_CHECK_TYPECHECK' is defined, the converter -macros become more complicated--they check the tag bits and/or the type -field in the first four bytes of a record type to ensure that the -object is really of the correct type. This is great for catching places -where an incorrect type is being dereferenced--this typically results -in a pointer being dereferenced as the wrong type of structure, with -unpredictable (and sometimes not easily traceable) results. - - There are similar `XSETTYPE()' macros that construct a Lisp object. -These macros are of the form `XSETTYPE (LVALUE, RESULT)', i.e. they -have to be a statement rather than just used in an expression. The -reason for this is that standard C doesn't let you "construct" a -structure (but GCC does). Granted, this sometimes isn't too -convenient; for the case of integers, at least, you can use the -function `make_int()', which constructs and _returns_ an integer Lisp -object. Note that the `XSETTYPE()' macros are also affected by -`ERROR_CHECK_TYPECHECK' and make sure that the structure is of the -right type in the case of record types, where the type is contained in -the structure. - - The C programmer is responsible for *guaranteeing* that a -Lisp_Object is the correct type before using the `XTYPE' macros. This -is especially important in the case of lists. Use `XCAR' and `XCDR' if -a Lisp_Object is certainly a cons cell, else use `Fcar()' and `Fcdr()'. -Trust other C code, but not Lisp code. On the other hand, if XEmacs -has an internal logic error, it's better to crash immediately, so -sprinkle `assert()'s and "unreachable" `abort()'s liberally about the -source code. Where performance is an issue, use `type_checking_assert', -`bufpos_checking_assert', and `gc_checking_assert', which do nothing -unless the corresponding configure error checking flag was specified. - - -File: internals.info, Node: Rules When Writing New C Code, Next: Regression Testing XEmacs, Prev: How Lisp Objects Are Represented in C, Up: Top - -Rules When Writing New C Code -***************************** - - The XEmacs C Code is extremely complex and intricate, and there are -many rules that are more or less consistently followed throughout the -code. Many of these rules are not obvious, so they are explained here. -It is of the utmost importance that you follow them. If you don't, -you may get something that appears to work, but which will crash in odd -situations, often in code far away from where the actual breakage is. +Buffers and Textual Representation +********************************** * Menu: -* General Coding Rules:: -* Writing Lisp Primitives:: -* Writing Good Comments:: -* Adding Global Lisp Variables:: -* Proper Use of Unsigned Types:: -* Coding for Mule:: -* Techniques for XEmacs Developers:: +* Introduction to Buffers:: A buffer holds a block of text such as a file. +* The Text in a Buffer:: Representation of the text in a buffer. +* Buffer Lists:: Keeping track of all buffers. +* Markers and Extents:: Tagging locations within a buffer. +* Bufbytes and Emchars:: Representation of individual characters. +* The Buffer Object:: The Lisp object corresponding to a buffer.  -File: internals.info, Node: General Coding Rules, Next: Writing Lisp Primitives, Up: Rules When Writing New C Code +File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Up: Buffers and Textual Representation -General Coding Rules +Introduction to Buffers +======================= + +A buffer is logically just a Lisp object that holds some text. In +this, it is like a string, but a buffer is optimized for frequent +insertion and deletion, while a string is not. Furthermore: + + 1. Buffers are "permanent" objects, i.e. once you create them, they + remain around, and need to be explicitly deleted before they go + away. + + 2. Each buffer has a unique name, which is a string. Buffers are + normally referred to by name. In this respect, they are like + symbols. + + 3. Buffers have a default insertion position, called "point". + Inserting text (unless you explicitly give a position) goes at + point, and moves point forward past the text. This is what is + going on when you type text into Emacs. + + 4. Buffers have lots of extra properties associated with them. + + 5. Buffers can be "displayed". What this means is that there exist a + number of "windows", which are objects that correspond to some + visible section of your display, and each window has an associated + buffer, and the current contents of the buffer are shown in that + section of the display. The redisplay mechanism (which takes care + of doing this) knows how to look at the text of a buffer and come + up with some reasonable way of displaying this. Many of the + properties of a buffer control how the buffer's text is displayed. + + 6. One buffer is distinguished and called the "current buffer". It is + stored in the variable `current_buffer'. Buffer operations operate + on this buffer by default. When you are typing text into a + buffer, the buffer you are typing into is always `current_buffer'. + Switching to a different window changes the current buffer. Note + that Lisp code can temporarily change the current buffer using + `set-buffer' (often enclosed in a `save-excursion' so that the + former current buffer gets restored when the code is finished). + However, calling `set-buffer' will NOT cause a permanent change in + the current buffer. The reason for this is that the top-level + event loop sets `current_buffer' to the buffer of the selected + window, each time it finishes executing a user command. + + Make sure you understand the distinction between "current buffer" +and "buffer of the selected window", and the distinction between +"point" of the current buffer and "window-point" of the selected +window. (This latter distinction is explained in detail in the section +on windows.) + + +File: internals.info, Node: The Text in a Buffer, Next: Buffer Lists, Prev: Introduction to Buffers, Up: Buffers and Textual Representation + +The Text in a Buffer ==================== - The C code is actually written in a dialect of C called "Clean C", -meaning that it can be compiled, mostly warning-free, with either a C or -C++ compiler. Coding in Clean C has several advantages over plain C. -C++ compilers are more nit-picking, and a number of coding errors have -been found by compiling with C++. The ability to use both C and C++ -tools means that a greater variety of development tools are available to -the developer. - - Every module includes `' (angle brackets so that -`--srcdir' works correctly; `config.h' may or may not be in the same -directory as the C sources) and `lisp.h'. `config.h' must always be -included before any other header files (including system header files) -to ensure that certain tricks played by various `s/' and `m/' files -work out correctly. - - When including header files, always use angle brackets, not double -quotes, except when the file to be included is always in the same -directory as the including file. If either file is a generated file, -then that is not likely to be the case. In order to understand why we -have this rule, imagine what happens when you do a build in the source -directory using `./configure' and another build in another directory -using `../work/configure'. There will be two different `config.h' -files. Which one will be used if you `#include "config.h"'? - - Almost every module contains a `syms_of_*()' function and a -`vars_of_*()' function. The former declares any Lisp primitives you -have defined and defines any symbols you will be using. The latter -declares any global Lisp variables you have added and initializes global -C variables in the module. *Important*: There are stringent -requirements on exactly what can go into these functions. See the -comment in `emacs.c'. The reason for this is to avoid obscure unwanted -interactions during initialization. If you don't follow these rules, -you'll be sorry! If you want to do anything that isn't allowed, create -a `complex_vars_of_*()' function for it. Doing this is tricky, though: -you have to make sure your function is called at the right time so that -all the initialization dependencies work out. - - Declare each function of these kinds in `symsinit.h'. Make sure -it's called in the appropriate place in `emacs.c'. You never need to -include `symsinit.h' directly, because it is included by `lisp.h'. - - *All global and static variables that are to be modifiable must be -declared uninitialized.* This means that you may not use the "declare -with initializer" form for these variables, such as `int some_variable -= 0;'. The reason for this has to do with some kludges done during the -dumping process: If possible, the initialized data segment is re-mapped -so that it becomes part of the (unmodifiable) code segment in the -dumped executable. This allows this memory to be shared among multiple -running XEmacs processes. XEmacs is careful to place as much constant -data as possible into initialized variables during the `temacs' phase. - - *Please note:* This kludge only works on a few systems nowadays, and -is rapidly becoming irrelevant because most modern operating systems -provide "copy-on-write" semantics. All data is initially shared -between processes, and a private copy is automatically made (on a -page-by-page basis) when a process first attempts to write to a page of -memory. - - Formerly, there was a requirement that static variables not be -declared inside of functions. This had to do with another hack along -the same vein as what was just described: old USG systems put -statically-declared variables in the initialized data space, so those -header files had a `#define static' declaration. (That way, the -data-segment remapping described above could still work.) This fails -badly on static variables inside of functions, which suddenly become -automatic variables; therefore, you weren't supposed to have any of -them. This awful kludge has been removed in XEmacs because - - 1. almost all of the systems that used this kludge ended up having to - disable the data-segment remapping anyway; - - 2. the only systems that didn't were extremely outdated ones; - - 3. this hack completely messed up inline functions. - - The C source code makes heavy use of C preprocessor macros. One -popular macro style is: - - #define FOO(var, value) do { \ - Lisp_Object FOO_value = (value); \ - ... /* compute using FOO_value */ \ - (var) = bar; \ - } while (0) - - The `do {...} while (0)' is a standard trick to allow FOO to have -statement semantics, so that it can safely be used within an `if' -statement in C, for example. Multiple evaluation is prevented by -copying a supplied argument into a local variable, so that -`FOO(var,fun(1))' only calls `fun' once. - - Lisp lists are popular data structures in the C code as well as in -Elisp. There are two sets of macros that iterate over lists. -`EXTERNAL_LIST_LOOP_N' should be used when the list has been supplied -by the user, and cannot be trusted to be acyclic and `nil'-terminated. -A `malformed-list' or `circular-list' error will be generated if the -list being iterated over is not entirely kosher. `LIST_LOOP_N', on the -other hand, is faster and less safe, and can be used only on trusted -lists. - - Related macros are `GET_EXTERNAL_LIST_LENGTH' and `GET_LIST_LENGTH', -which calculate the length of a list, and in the case of -`GET_EXTERNAL_LIST_LENGTH', validating the properness of the list. The -macros `EXTERNAL_LIST_LOOP_DELETE_IF' and `LIST_LOOP_DELETE_IF' delete -elements from a lisp list satisfying some predicate. +The text in a buffer consists of a sequence of zero or more characters. +A "character" is an integer that logically represents a letter, +number, space, or other unit of text. Most of the characters that you +will typically encounter belong to the ASCII set of characters, but +there are also characters for various sorts of accented letters, +special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana, +etc.), Cyrillic and Greek letters, etc. The actual number of possible +characters is quite large. + + For now, we can view a character as some non-negative integer that +has some shape that defines how it typically appears (e.g. as an +uppercase A). (The exact way in which a character appears depends on the +font used to display the character.) The internal type of characters in +the C code is an `Emchar'; this is just an `int', but using a symbolic +type makes the code clearer. + + Between every character in a buffer is a "buffer position" or +"character position". We can speak of the character before or after a +particular buffer position, and when you insert a character at a +particular position, all characters after that position end up at new +positions. When we speak of the character "at" a position, we really +mean the character after the position. (This schizophrenia between a +buffer position being "between" a character and "on" a character is +rampant in Emacs.) + + Buffer positions are numbered starting at 1. This means that +position 1 is before the first character, and position 0 is not valid. +If there are N characters in a buffer, then buffer position N+1 is +after the last one, and position N+2 is not valid. + + The internal makeup of the Emchar integer varies depending on whether +we have compiled with MULE support. If not, the Emchar integer is an +8-bit integer with possible values from 0 - 255. 0 - 127 are the +standard ASCII characters, while 128 - 255 are the characters from the +ISO-8859-1 character set. If we have compiled with MULE support, an +Emchar is a 19-bit integer, with the various bits having meanings +according to a complex scheme that will be detailed later. The +characters numbered 0 - 255 still have the same meanings as for the +non-MULE case, though. + + Internally, the text in a buffer is represented in a fairly simple +fashion: as a contiguous array of bytes, with a "gap" of some size in +the middle. Although the gap is of some substantial size in bytes, +there is no text contained within it: From the perspective of the text +in the buffer, it does not exist. The gap logically sits at some buffer +position, between two characters (or possibly at the beginning or end of +the buffer). Insertion of text in a buffer at a particular position is +always accomplished by first moving the gap to that position (i.e. +through some block moving of text), then writing the text into the +beginning of the gap, thereby shrinking the gap. If the gap shrinks +down to nothing, a new gap is created. (What actually happens is that a +new gap is "created" at the end of the buffer's text, which requires +nothing more than changing a couple of indices; then the gap is "moved" +to the position where the insertion needs to take place by moving up in +memory all the text after that position.) Similarly, deletion occurs +by moving the gap to the place where the text is to be deleted, and +then simply expanding the gap to include the deleted text. +("Expanding" and "shrinking" the gap as just described means just that +the internal indices that keep track of where the gap is located are +changed.) + + Note that the total amount of memory allocated for a buffer text +never decreases while the buffer is live. Therefore, if you load up a +20-megabyte file and then delete all but one character, there will be a +20-megabyte gap, which won't get any smaller (except by inserting +characters back again). Once the buffer is killed, the memory allocated +for the buffer text will be freed, but it will still be sitting on the +heap, taking up virtual memory, and will not be released back to the +operating system. (However, if you have compiled XEmacs with rel-alloc, +the situation is different. In this case, the space _will_ be released +back to the operating system. However, this tends to result in a +noticeable speed penalty.) + + Astute readers may notice that the text in a buffer is represented as +an array of _bytes_, while (at least in the MULE case) an Emchar is a +19-bit integer, which clearly cannot fit in a byte. This means (of +course) that the text in a buffer uses a different representation from +an Emchar: specifically, the 19-bit Emchar becomes a series of one to +four bytes. The conversion between these two representations is complex +and will be described later. + + In the non-MULE case, everything is very simple: An Emchar is an +8-bit value, which fits neatly into one byte. + + If we are given a buffer position and want to retrieve the character +at that position, we need to follow these steps: + + 1. Pretend there's no gap, and convert the buffer position into a + "byte index" that indexes to the appropriate byte in the buffer's + stream of textual bytes. By convention, byte indices begin at 1, + just like buffer positions. In the non-MULE case, byte indices + and buffer positions are identical, since one character equals one + byte. + + 2. Convert the byte index into a "memory index", which takes the gap + into account. The memory index is a direct index into the block of + memory that stores the text of a buffer. This basically just + involves checking to see if the byte index is past the gap, and if + so, adding the size of the gap to it. By convention, memory + indices begin at 1, just like buffer positions and byte indices, + and when referring to the position that is "at" the gap, we always + use the memory position at the _beginning_, not at the end, of the + gap. + + 3. Fetch the appropriate bytes at the determined memory position. + + 4. Convert these bytes into an Emchar. + + In the non-Mule case, (3) and (4) boil down to a simple one-byte +memory access. + + Note that we have defined three types of positions in a buffer: + + 1. "buffer positions" or "character positions", typedef `Bufpos' + + 2. "byte indices", typedef `Bytind' + + 3. "memory indices", typedef `Memind' + + All three typedefs are just `int's, but defining them this way makes +things a lot clearer. + + Most code works with buffer positions. In particular, all Lisp code +that refers to text in a buffer uses buffer positions. Lisp code does +not know that byte indices or memory indices exist. + + Finally, we have a typedef for the bytes in a buffer. This is a +`Bufbyte', which is an unsigned char. Referring to them as Bufbytes +underscores the fact that we are working with a string of bytes in the +internal Emacs buffer representation rather than in one of a number of +possible alternative representations (e.g. EUC-encoded text, etc.). + + +File: internals.info, Node: Buffer Lists, Next: Markers and Extents, Prev: The Text in a Buffer, Up: Buffers and Textual Representation + +Buffer Lists +============ + +Recall earlier that buffers are "permanent" objects, i.e. that they +remain around until explicitly deleted. This entails that there is a +list of all the buffers in existence. This list is actually an +assoc-list (mapping from the buffer's name to the buffer) and is stored +in the global variable `Vbuffer_alist'. + + The order of the buffers in the list is important: the buffers are +ordered approximately from most-recently-used to least-recently-used. +Switching to a buffer using `switch-to-buffer', `pop-to-buffer', etc. +and switching windows using `other-window', etc. usually brings the +new current buffer to the front of the list. `switch-to-buffer', +`other-buffer', etc. look at the beginning of the list to find an +alternative buffer to suggest. You can also explicitly move a buffer +to the end of the list using `bury-buffer'. + + In addition to the global ordering in `Vbuffer_alist', each frame +has its own ordering of the list. These lists always contain the same +elements as in `Vbuffer_alist' although possibly in a different order. +`buffer-list' normally returns the list for the selected frame. This +allows you to work in separate frames without things interfering with +each other. + + The standard way to look up a buffer given a name is `get-buffer', +and the standard way to create a new buffer is `get-buffer-create', +which looks up a buffer with a given name, creating a new one if +necessary. These operations correspond exactly with the symbol +operations `intern-soft' and `intern', respectively. You can also +force a new buffer to be created using `generate-new-buffer', which +takes a name and (if necessary) makes a unique name from this by +appending a number, and then creates the buffer. This is basically +like the symbol operation `gensym'. + + +File: internals.info, Node: Markers and Extents, Next: Bufbytes and Emchars, Prev: Buffer Lists, Up: Buffers and Textual Representation + +Markers and Extents +=================== + +Among the things associated with a buffer are things that are logically +attached to certain buffer positions. This can be used to keep track +of a buffer position when text is inserted and deleted, so that it +remains at the same spot relative to the text around it; to assign +properties to particular sections of text; etc. There are two such +objects that are useful in this regard: they are "markers" and +"extents". + + A "marker" is simply a flag placed at a particular buffer position, +which is moved around as text is inserted and deleted. Markers are +used for all sorts of purposes, such as the `mark' that is the other +end of textual regions to be cut, copied, etc. + + An "extent" is similar to two markers plus some associated +properties, and is used to keep track of regions in a buffer as text is +inserted and deleted, and to add properties (e.g. fonts) to particular +regions of text. The external interface of extents is explained +elsewhere. + + The important thing here is that markers and extents simply contain +buffer positions in them as integers, and every time text is inserted or +deleted, these positions must be updated. In order to minimize the +amount of shuffling that needs to be done, the positions in markers and +extents (there's one per marker, two per extent) are stored in Meminds. +This means that they only need to be moved when the text is physically +moved in memory; since the gap structure tries to minimize this, it also +minimizes the number of marker and extent indices that need to be +adjusted. Look in `insdel.c' for the details of how this works. + + One other important distinction is that markers are "temporary" +while extents are "permanent". This means that markers disappear as +soon as there are no more pointers to them, and correspondingly, there +is no way to determine what markers are in a buffer if you are just +given the buffer. Extents remain in a buffer until they are detached +(which could happen as a result of text being deleted) or the buffer is +deleted, and primitives do exist to enumerate the extents in a buffer. + + +File: internals.info, Node: Bufbytes and Emchars, Next: The Buffer Object, Prev: Markers and Extents, Up: Buffers and Textual Representation + +Bufbytes and Emchars +==================== + +Not yet documented. + + +File: internals.info, Node: The Buffer Object, Prev: Bufbytes and Emchars, Up: Buffers and Textual Representation + +The Buffer Object +================= + +Buffers contain fields not directly accessible by the Lisp programmer. +We describe them here, naming them by the names used in the C code. +Many are accessible indirectly in Lisp programs via Lisp primitives. + +`name' + The buffer name is a string that names the buffer. It is + guaranteed to be unique. *Note Buffer Names: (lispref)Buffer + Names. + +`save_modified' + This field contains the time when the buffer was last saved, as an + integer. *Note Buffer Modification: (lispref)Buffer Modification. + +`modtime' + This field contains the modification time of the visited file. It + is set when the file is written or read. Every time the buffer is + written to the file, this field is compared to the modification + time of the file. *Note Buffer Modification: (lispref)Buffer + Modification. + +`auto_save_modified' + This field contains the time when the buffer was last auto-saved. + +`last_window_start' + This field contains the `window-start' position in the buffer as of + the last time the buffer was displayed in a window. + +`undo_list' + This field points to the buffer's undo list. *Note Undo: + (lispref)Undo. + +`syntax_table_v' + This field contains the syntax table for the buffer. *Note Syntax + Tables: (lispref)Syntax Tables. + +`downcase_table' + This field contains the conversion table for converting text to + lower case. *Note Case Tables: (lispref)Case Tables. + +`upcase_table' + This field contains the conversion table for converting text to + upper case. *Note Case Tables: (lispref)Case Tables. + +`case_canon_table' + This field contains the conversion table for canonicalizing text + for case-folding search. *Note Case Tables: (lispref)Case Tables. + +`case_eqv_table' + This field contains the equivalence table for case-folding search. + *Note Case Tables: (lispref)Case Tables. + +`display_table' + This field contains the buffer's display table, or `nil' if it + doesn't have one. *Note Display Tables: (lispref)Display Tables. + +`markers' + This field contains the chain of all markers that currently point + into the buffer. Deletion of text in the buffer, and motion of + the buffer's gap, must check each of these markers and perhaps + update it. *Note Markers: (lispref)Markers. + +`backed_up' + This field is a flag that tells whether a backup file has been + made for the visited file of this buffer. + +`mark' + This field contains the mark for the buffer. The mark is a marker, + hence it is also included on the list `markers'. *Note The Mark: + (lispref)The Mark. + +`mark_active' + This field is non-`nil' if the buffer's mark is active. + +`local_var_alist' + This field contains the association list describing the variables + local in this buffer, and their values, with the exception of + local variables that have special slots in the buffer object. + (Those slots are omitted from this table.) *Note Buffer-Local + Variables: (lispref)Buffer-Local Variables. + +`modeline_format' + This field contains a Lisp object which controls how to display + the mode line for this buffer. *Note Modeline Format: + (lispref)Modeline Format. + +`base_buffer' + This field holds the buffer's base buffer (if it is an indirect + buffer), or `nil'. + + +File: internals.info, Node: MULE Character Sets and Encodings, Next: The Lisp Reader and Compiler, Prev: Buffers and Textual Representation, Up: Top + +MULE Character Sets and Encodings +********************************* + +Recall that there are two primary ways that text is represented in +XEmacs. The "buffer" representation sees the text as a series of bytes +(Bufbytes), with a variable number of bytes used per character. The +"character" representation sees the text as a series of integers +(Emchars), one per character. The character representation is a cleaner +representation from a theoretical standpoint, and is thus used in many +cases when lots of manipulations on a string need to be done. However, +the buffer representation is the standard representation used in both +Lisp strings and buffers, and because of this, it is the "default" +representation that text comes in. The reason for using this +representation is that it's compact and is compatible with ASCII. + +* Menu: + +* Character Sets:: +* Encodings:: +* Internal Mule Encodings:: +* CCL:: + + +File: internals.info, Node: Character Sets, Next: Encodings, Up: MULE Character Sets and Encodings + +Character Sets +============== + +A character set (or "charset") is an ordered set of characters. A +particular character in a charset is indexed using one or more +"position codes", which are non-negative integers. The number of +position codes needed to identify a particular character in a charset is +called the "dimension" of the charset. In XEmacs/Mule, all charsets +have dimension 1 or 2, and the size of all charsets (except for a few +special cases) is either 94, 96, 94 by 94, or 96 by 96. The range of +position codes used to index characters from any of these types of +character sets is as follows: + + Charset type Position code 1 Position code 2 + ------------------------------------------------------------ + 94 33 - 126 N/A + 96 32 - 127 N/A + 94x94 33 - 126 33 - 126 + 96x96 32 - 127 32 - 127 + + Note that in the above cases position codes do not start at an +expected value such as 0 or 1. The reason for this will become clear +later. + + For example, Latin-1 is a 96-character charset, and JISX0208 (the +Japanese national character set) is a 94x94-character charset. + + [Note that, although the ranges above define the _valid_ position +codes for a charset, some of the slots in a particular charset may in +fact be empty. This is the case for JISX0208, for example, where (e.g.) +all the slots whose first position code is in the range 118 - 127 are +empty.] + + There are three charsets that do not follow the above rules. All of +them have one dimension, and have ranges of position codes as follows: + + Charset name Position code 1 + ------------------------------------ + ASCII 0 - 127 + Control-1 0 - 31 + Composite 0 - some large number + + (The upper bound of the position code for composite characters has +not yet been determined, but it will probably be at least 16,383). + + ASCII is the union of two subsidiary character sets: Printing-ASCII +(the printing ASCII character set, consisting of position codes 33 - +126, like for a standard 94-character charset) and Control-ASCII (the +non-printing characters that would appear in a binary file with codes 0 +- 32 and 127). + + Control-1 contains the non-printing characters that would appear in a +binary file with codes 128 - 159. + + Composite contains characters that are generated by overstriking one +or more characters from other charsets. + + Note that some characters in ASCII, and all characters in Control-1, +are "control" (non-printing) characters. These have no printed +representation but instead control some other function of the printing +(e.g. TAB or 8 moves the current character position to the next tab +stop). All other characters in all charsets are "graphic" (printing) +characters. + + When a binary file is read in, the bytes in the file are assigned to +character sets as follows: + + Bytes Character set Range + -------------------------------------------------- + 0 - 127 ASCII 0 - 127 + 128 - 159 Control-1 0 - 31 + 160 - 255 Latin-1 32 - 127 + + This is a bit ad-hoc but gets the job done.  -File: internals.info, Node: Writing Lisp Primitives, Next: Writing Good Comments, Prev: General Coding Rules, Up: Rules When Writing New C Code +File: internals.info, Node: Encodings, Next: Internal Mule Encodings, Prev: Character Sets, Up: MULE Character Sets and Encodings + +Encodings +========= + +An "encoding" is a way of numerically representing characters from one +or more character sets. If an encoding only encompasses one character +set, then the position codes for the characters in that character set +could be used directly. This is not possible, however, if more than +one character set is to be used in the encoding. + + For example, the conversion detailed above between bytes in a binary +file and characters is effectively an encoding that encompasses the +three character sets ASCII, Control-1, and Latin-1 in a stream of 8-bit +bytes. + + Thus, an encoding can be viewed as a way of encoding characters from +a specified group of character sets using a stream of bytes, each of +which contains a fixed number of bits (but not necessarily 8, as in the +common usage of "byte"). + + Here are descriptions of a couple of common encodings: + +* Menu: + +* Japanese EUC (Extended Unix Code):: +* JIS7:: + + +File: internals.info, Node: Japanese EUC (Extended Unix Code), Next: JIS7, Up: Encodings + +Japanese EUC (Extended Unix Code) +--------------------------------- + +This encompasses the character sets Printing-ASCII, Japanese-JISX0201, +and Japanese-JISX0208-Kana (half-width katakana, the right half of +JISX0201). It uses 8-bit bytes. + + Note that Printing-ASCII and Japanese-JISX0201-Kana are 94-character +charsets, while Japanese-JISX0208 is a 94x94-character charset. + + The encoding is as follows: + + Character set Representation (PC=position-code) + ------------- -------------- + Printing-ASCII PC1 + Japanese-JISX0201-Kana 0x8E | PC1 + 0x80 + Japanese-JISX0208 PC1 + 0x80 | PC2 + 0x80 + Japanese-JISX0212 PC1 + 0x80 | PC2 + 0x80 + + +File: internals.info, Node: JIS7, Prev: Japanese EUC (Extended Unix Code), Up: Encodings + +JIS7 +---- + +This encompasses the character sets Printing-ASCII, +Japanese-JISX0201-Roman (the left half of JISX0201; this character set +is very similar to Printing-ASCII and is a 94-character charset), +Japanese-JISX0208, and Japanese-JISX0201-Kana. It uses 7-bit bytes. + + Unlike Japanese EUC, this is a "modal" encoding, which means that +there are multiple states that the encoding can be in, which affect how +the bytes are to be interpreted. Special sequences of bytes (called +"escape sequences") are used to change states. + + The encoding is as follows: + + Character set Representation (PC=position-code) + ------------- -------------- + Printing-ASCII PC1 + Japanese-JISX0201-Roman PC1 + Japanese-JISX0201-Kana PC1 + Japanese-JISX0208 PC1 PC2 + + + Escape sequence ASCII equivalent Meaning + --------------- ---------------- ------- + 0x1B 0x28 0x4A ESC ( J invoke Japanese-JISX0201-Roman + 0x1B 0x28 0x49 ESC ( I invoke Japanese-JISX0201-Kana + 0x1B 0x24 0x42 ESC $ B invoke Japanese-JISX0208 + 0x1B 0x28 0x42 ESC ( B invoke Printing-ASCII + + Initially, Printing-ASCII is invoked. -Writing Lisp Primitives + +File: internals.info, Node: Internal Mule Encodings, Next: CCL, Prev: Encodings, Up: MULE Character Sets and Encodings + +Internal Mule Encodings ======================= - Lisp primitives are Lisp functions implemented in C. The details of -interfacing the C function so that Lisp can call it are handled by a few -C macros. The only way to really understand how to write new C code is -to read the source, but we can explain some things here. - - An example of a special form is the definition of `prog1', from -`eval.c'. (An ordinary function would have the same general -appearance.) - - DEFUN ("prog1", Fprog1, 1, UNEVALLED, 0, /* - Similar to `progn', but the value of the first form is returned. - \(prog1 FIRST BODY...): All the arguments are evaluated sequentially. - The value of FIRST is saved during evaluation of the remaining args, - whose values are discarded. - */ - (args)) - { - /* This function can GC */ - REGISTER Lisp_Object val, form, tail; - struct gcpro gcpro1; - - val = Feval (XCAR (args)); - - GCPRO1 (val); - - LIST_LOOP_3 (form, XCDR (args), tail) - Feval (form); - - UNGCPRO; - return val; - } - - Let's start with a precise explanation of the arguments to the -`DEFUN' macro. Here is a template for them: - - DEFUN (LNAME, FNAME, MIN_ARGS, MAX_ARGS, INTERACTIVE, /* - DOCSTRING - */ - (ARGLIST)) - -LNAME - This string is the name of the Lisp symbol to define as the - function name; in the example above, it is `"prog1"'. - -FNAME - This is the C function name for this function. This is the name - that is used in C code for calling the function. The name is, by - convention, `F' prepended to the Lisp name, with all dashes (`-') - in the Lisp name changed to underscores. Thus, to call this - function from C code, call `Fprog1'. Remember that the arguments - are of type `Lisp_Object'; various macros and functions for - creating values of type `Lisp_Object' are declared in the file - `lisp.h'. - - Primitives whose names are special characters (e.g. `+' or `<') - are named by spelling out, in some fashion, the special character: - e.g. `Fplus()' or `Flss()'. Primitives whose names begin with - normal alphanumeric characters but also contain special characters - are spelled out in some creative way, e.g. `let*' becomes - `FletX()'. - - Each function also has an associated structure that holds the data - for the subr object that represents the function in Lisp. This - structure conveys the Lisp symbol name to the initialization - routine that will create the symbol and store the subr object as - its definition. The C variable name of this structure is always - `S' prepended to the FNAME. You hardly ever need to be aware of - the existence of this structure, since `DEFUN' plus `DEFSUBR' - takes care of all the details. - -MIN_ARGS - This is the minimum number of arguments that the function - requires. The function `prog1' allows a minimum of one argument. - -MAX_ARGS - This is the maximum number of arguments that the function accepts, - if there is a fixed maximum. Alternatively, it can be `UNEVALLED', - indicating a special form that receives unevaluated arguments, or - `MANY', indicating an unlimited number of evaluated arguments (the - C equivalent of `&rest'). Both `UNEVALLED' and `MANY' are macros. - If MAX_ARGS is a number, it may not be less than MIN_ARGS and it - may not be greater than 8. (If you need to add a function with - more than 8 arguments, use the `MANY' form. Resist the urge to - edit the definition of `DEFUN' in `lisp.h'. If you do it anyways, - make sure to also add another clause to the switch statement in - `primitive_funcall().') - -INTERACTIVE - This is an interactive specification, a string such as might be - used as the argument of `interactive' in a Lisp function. In the - case of `prog1', it is 0 (a null pointer), indicating that `prog1' - cannot be called interactively. A value of `""' indicates a - function that should receive no arguments when called - interactively. - -DOCSTRING - This is the documentation string. It is written just like a - documentation string for a function defined in Lisp; in - particular, the first line should be a single sentence. Note how - the documentation string is enclosed in a comment, none of the - documentation is placed on the same lines as the comment-start and - comment-end characters, and the comment-start characters are on - the same line as the interactive specification. `make-docfile', - which scans the C files for documentation strings, is very - particular about what it looks for, and will not properly extract - the doc string if it's not in this exact format. - - In order to make both `etags' and `make-docfile' happy, make sure - that the `DEFUN' line contains the LNAME and FNAME, and that the - comment-start characters for the doc string are on the same line - as the interactive specification, and put a newline directly after - them (and before the comment-end characters). - -ARGLIST - This is the comma-separated list of arguments to the C function. - For a function with a fixed maximum number of arguments, provide a - C argument for each Lisp argument. In this case, unlike regular C - functions, the types of the arguments are not declared; they are - simply always of type `Lisp_Object'. - - The names of the C arguments will be used as the names of the - arguments to the Lisp primitive as displayed in its documentation, - modulo the same concerns described above for `F...' names (in - particular, underscores in the C arguments become dashes in the - Lisp arguments). - - There is one additional kludge: A trailing `_' on the C argument is - discarded when forming the Lisp argument. This allows C language - reserved words (like `default') or global symbols (like `dirname') - to be used as argument names without compiler warnings or errors. - - A Lisp function with MAX_ARGS = `UNEVALLED' is a "special form"; - its arguments are not evaluated. Instead it receives one argument - of type `Lisp_Object', a (Lisp) list of the unevaluated arguments, - conventionally named `(args)'. - - When a Lisp function has no upper limit on the number of arguments, - specify MAX_ARGS = `MANY'. In this case its implementation in C - actually receives exactly two arguments: the number of Lisp - arguments (an `int') and the address of a block containing their - values (a `Lisp_Object *'). In this case only are the C types - specified in the ARGLIST: `(int nargs, Lisp_Object *args)'. - - - Within the function `Fprog1' itself, note the use of the macros -`GCPRO1' and `UNGCPRO'. `GCPRO1' is used to "protect" a variable from -garbage collection--to inform the garbage collector that it must look -in that variable and regard the object pointed at by its contents as an -accessible object. This is necessary whenever you call `Feval' or -anything that can directly or indirectly call `Feval' (this includes -the `QUIT' macro!). At such a time, any Lisp object that you intend to -refer to again must be protected somehow. `UNGCPRO' cancels the -protection of the variables that are protected in the current function. -It is necessary to do this explicitly. - - The macro `GCPRO1' protects just one local variable. If you want to -protect two, use `GCPRO2' instead; repeating `GCPRO1' will not work. -Macros `GCPRO3' and `GCPRO4' also exist. - - These macros implicitly use local variables such as `gcpro1'; you -must declare these explicitly, with type `struct gcpro'. Thus, if you -use `GCPRO2', you must declare `gcpro1' and `gcpro2'. - - Note also that the general rule is "caller-protects"; i.e. you are -only responsible for protecting those Lisp objects that you create. Any -objects passed to you as arguments should have been protected by whoever -created them, so you don't in general have to protect them. - - In particular, the arguments to any Lisp primitive are always -automatically `GCPRO'ed, when called "normally" from Lisp code or -bytecode. So only a few Lisp primitives that are called frequently from -C code, such as `Fprogn' protect their arguments as a service to their -caller. You don't need to protect your arguments when writing a new -`DEFUN'. - - `GCPRO'ing is perhaps the trickiest and most error-prone part of -XEmacs coding. It is *extremely* important that you get this right and -use a great deal of discipline when writing this code. *Note -`GCPRO'ing: GCPROing, for full details on how to do this. - - What `DEFUN' actually does is declare a global structure of type -`Lisp_Subr' whose name begins with capital `SF' and which contains -information about the primitive (e.g. a pointer to the function, its -minimum and maximum allowed arguments, a string describing its Lisp -name); `DEFUN' then begins a normal C function declaration using the -`F...' name. The Lisp subr object that is the function definition of a -primitive (i.e. the object in the function slot of the symbol that -names the primitive) actually points to this `SF' structure; when -`Feval' encounters a subr, it looks in the structure to find out how to -call the C function. - - Defining the C function is not enough to make a Lisp primitive -available; you must also create the Lisp symbol for the primitive (the -symbol is "interned"; *note Obarrays::) and store a suitable subr -object in its function cell. (If you don't do this, the primitive won't -be seen by Lisp code.) The code looks like this: - - DEFSUBR (FNAME); - -Here FNAME is the same name you used as the second argument to `DEFUN'. - - This call to `DEFSUBR' should go in the `syms_of_*()' function at -the end of the module. If no such function exists, create it and make -sure to also declare it in `symsinit.h' and call it from the -appropriate spot in `main()'. *Note General Coding Rules::. - - Note that C code cannot call functions by name unless they are -defined in C. The way to call a function written in Lisp from C is to -use `Ffuncall', which embodies the Lisp function `funcall'. Since the -Lisp function `funcall' accepts an unlimited number of arguments, in C -it takes two: the number of Lisp-level arguments, and a one-dimensional -array containing their values. The first Lisp-level argument is the -Lisp function to call, and the rest are the arguments to pass to it. -Since `Ffuncall' can call the evaluator, you must protect pointers from -garbage collection around the call to `Ffuncall'. (However, `Ffuncall' -explicitly protects all of its parameters, so you don't have to protect -any pointers passed as parameters to it.) - - The C functions `call0', `call1', `call2', and so on, provide handy -ways to call a Lisp function conveniently with a fixed number of -arguments. They work by calling `Ffuncall'. - - `eval.c' is a very good file to look through for examples; `lisp.h' -contains the definitions for important macros and functions. - - -File: internals.info, Node: Writing Good Comments, Next: Adding Global Lisp Variables, Prev: Writing Lisp Primitives, Up: Rules When Writing New C Code - -Writing Good Comments -===================== - - Comments are a lifeline for programmers trying to understand tricky -code. In general, the less obvious it is what you are doing, the more -you need a comment, and the more detailed it needs to be. You should -always be on guard when you're writing code for stuff that's tricky, and -should constantly be putting yourself in someone else's shoes and asking -if that person could figure out without much difficulty what's going -on. (Assume they are a competent programmer who understands the -essentials of how the XEmacs code is structured but doesn't know much -about the module you're working on or any algorithms you're using.) If -you're not sure whether they would be able to, add a comment. Always -err on the side of more comments, rather than less. - - Generally, when making comments, there is no need to attribute them -with your name or initials. This especially goes for small, -easy-to-understand, non-opinionated ones. Also, comments indicating -where, when, and by whom a file was changed are _strongly_ discouraged, -and in general will be removed as they are discovered. This is exactly -what `ChangeLogs' are there for. However, it can occasionally be -useful to mark exactly where (but not when or by whom) changes are -made, particularly when making small changes to a file imported from -elsewhere. These marks help when later on a newer version of the file -is imported and the changes need to be merged. (If everything were -always kept in CVS, there would be no need for this. But in practice, -this often doesn't happen, or the CVS repository is later on lost or -unavailable to the person doing the update.) - - When putting in an explicit opinion in a comment, you should -_always_ attribute it with your name, and optionally the date. This -also goes for long, complex comments explaining in detail the workings -of something - by putting your name there, you make it possible for -someone who has questions about how that thing works to determine who -wrote the comment so they can write to them. Preferably, use your -actual name and not your initials, unless your initials are generally -recognized (e.g. `jwz'). You can use only your first name if it's -obvious who you are; otherwise, give first and last name. If you're -not a regular contributor, you might consider putting your email -address in - it may be in the ChangeLog, but after awhile ChangeLogs -have a tendency of disappearing or getting muddled. (E.g. your comment -may get copied somewhere else or even into another program, and -tracking down the proper ChangeLog may be very difficult.) - - If you come across an opinion that is not or no longer valid, or you -come across any comment that no longer applies but you want to keep it -around, enclose it in `[[ ' and ` ]]' marks and add a comment -afterwards explaining why the preceding comment is no longer valid. Put -your name on this comment, as explained above. - - Just as comments are a lifeline to programmers, incorrect comments -are death. If you come across an incorrect comment, *immediately* -correct it or flag it as incorrect, as described in the previous -paragraph. Whenever you work on a section of code, _always_ make sure -to update any comments to be correct - or, at the very least, flag them -as incorrect. - - To indicate a "todo" or other problem, use four pound signs - i.e. -`####'. - - -File: internals.info, Node: Adding Global Lisp Variables, Next: Proper Use of Unsigned Types, Prev: Writing Good Comments, Up: Rules When Writing New C Code - -Adding Global Lisp Variables -============================ - - Global variables whose names begin with `Q' are constants whose -value is a symbol of a particular name. The name of the variable should -be derived from the name of the symbol using the same rules as for Lisp -primitives. These variables are initialized using a call to -`defsymbol()' in the `syms_of_*()' function. (This call interns a -symbol, sets the C variable to the resulting Lisp object, and calls -`staticpro()' on the C variable to tell the garbage-collection -mechanism about this variable. What `staticpro()' does is add a -pointer to the variable to a large global array; when -garbage-collection happens, all pointers listed in the array are used -as starting points for marking Lisp objects. This is important because -it's quite possible that the only current reference to the object is -the C variable. In the case of symbols, the `staticpro()' doesn't -matter all that much because the symbol is contained in `obarray', -which is itself `staticpro()'ed. However, it's possible that a naughty -user could do something like uninterning the symbol out of `obarray' or -even setting `obarray' to a different value [although this is likely to -make XEmacs crash!].) - - *Please note:* It is potentially deadly if you declare a `Q...' -variable in two different modules. The two calls to `defsymbol()' are -no problem, but some linkers will complain about multiply-defined -symbols. The most insidious aspect of this is that often the link will -succeed anyway, but then the resulting executable will sometimes crash -in obscure ways during certain operations! To avoid this problem, -declare any symbols with common names (such as `text') that are not -obviously associated with this particular module in the module -`general.c'. - - Global variables whose names begin with `V' are variables that -contain Lisp objects. The convention here is that all global variables -of type `Lisp_Object' begin with `V', and all others don't (including -integer and boolean variables that have Lisp equivalents). Most of the -time, these variables have equivalents in Lisp, but some don't. Those -that do are declared this way by a call to `DEFVAR_LISP()' in the -`vars_of_*()' initializer for the module. What this does is create a -special "symbol-value-forward" Lisp object that contains a pointer to -the C variable, intern a symbol whose name is as specified in the call -to `DEFVAR_LISP()', and set its value to the symbol-value-forward Lisp -object; it also calls `staticpro()' on the C variable to tell the -garbage-collection mechanism about the variable. When `eval' (or -actually `symbol-value') encounters this special object in the process -of retrieving a variable's value, it follows the indirection to the C -variable and gets its value. `setq' does similar things so that the C -variable gets changed. - - Whether or not you `DEFVAR_LISP()' a variable, you need to -initialize it in the `vars_of_*()' function; otherwise it will end up -as all zeroes, which is the integer 0 (_not_ `nil'), and this is -probably not what you want. Also, if the variable is not -`DEFVAR_LISP()'ed, *you must call* `staticpro()' on the C variable in -the `vars_of_*()' function. Otherwise, the garbage-collection -mechanism won't know that the object in this variable is in use, and -will happily collect it and reuse its storage for another Lisp object, -and you will be the one who's unhappy when you can't figure out how -your variable got overwritten. - - -File: internals.info, Node: Proper Use of Unsigned Types, Next: Coding for Mule, Prev: Adding Global Lisp Variables, Up: Rules When Writing New C Code - -Proper Use of Unsigned Types -============================ - - Avoid using `unsigned int' and `unsigned long' whenever possible. -Unsigned types are viral - any arithmetic or comparisons involving -mixed signed and unsigned types are automatically converted to -unsigned, which is almost certainly not what you want. Many subtle and -hard-to-find bugs are created by careless use of unsigned types. In -general, you should almost _never_ use an unsigned type to hold a -regular quantity of any sort. The only exceptions are - - 1. When there's a reasonable possibility you will actually need all - 32 or 64 bits to store the quantity. - - 2. When calling existing API's that require unsigned types. In this - case, you should still do all manipulation using signed types, and - do the conversion at the very threshold of the API call. - - 3. In existing code that you don't want to modify because you don't - maintain it. - - 4. In bit-field structures. +In XEmacs/Mule, each character set is assigned a unique number, called a +"leading byte". This is used in the encodings of a character. Leading +bytes are in the range 0x80 - 0xFF (except for ASCII, which has a +leading byte of 0), although some leading bytes are reserved. + + Charsets whose leading byte is in the range 0x80 - 0x9F are called +"official" and are used for built-in charsets. Other charsets are +called "private" and have leading bytes in the range 0xA0 - 0xFF; these +are user-defined charsets. + + More specifically: + + Character set Leading byte + ------------- ------------ + ASCII 0 + Composite 0x80 + Dimension-1 Official 0x81 - 0x8D + (0x8E is free) + Control-1 0x8F + Dimension-2 Official 0x90 - 0x99 + (0x9A - 0x9D are free; + 0x9E and 0x9F are reserved) + Dimension-1 Private 0xA0 - 0xEF + Dimension-2 Private 0xF0 - 0xFF + + There are two internal encodings for characters in XEmacs/Mule. One +is called "string encoding" and is an 8-bit encoding that is used for +representing characters in a buffer or string. It uses 1 to 4 bytes per +character. The other is called "character encoding" and is a 19-bit +encoding that is used for representing characters individually in a +variable. + + (In the following descriptions, we'll ignore composite characters for +the moment. We also give a general (structural) overview first, +followed later by the exact details.) + +* Menu: + +* Internal String Encoding:: +* Internal Character Encoding:: + + +File: internals.info, Node: Internal String Encoding, Next: Internal Character Encoding, Up: Internal Mule Encodings + +Internal String Encoding +------------------------ + +ASCII characters are encoded using their position code directly. Other +characters are encoded using their leading byte followed by their +position code(s) with the high bit set. Characters in private character +sets have their leading byte prefixed with a "leading byte prefix", +which is either 0x9E or 0x9F. (No character sets are ever assigned these +leading bytes.) Specifically: + + Character set Encoding (PC=position-code, LB=leading-byte) + ------------- -------- + ASCII PC-1 | + Control-1 LB | PC1 + 0xA0 | + Dimension-1 official LB | PC1 + 0x80 | + Dimension-1 private 0x9E | LB | PC1 + 0x80 | + Dimension-2 official LB | PC1 + 0x80 | PC2 + 0x80 | + Dimension-2 private 0x9F | LB | PC1 + 0x80 | PC2 + 0x80 + + The basic characteristic of this encoding is that the first byte of +all characters is in the range 0x00 - 0x9F, and the second and +following bytes of all characters is in the range 0xA0 - 0xFF. This +means that it is impossible to get out of sync, or more specifically: + + 1. Given any byte position, the beginning of the character it is + within can be determined in constant time. + + 2. Given any byte position at the beginning of a character, the + beginning of the next character can be determined in constant time. + + 3. Given any byte position at the beginning of a character, the + beginning of the previous character can be determined in constant + time. + + 4. Textual searches can simply treat encoded strings as if they were + encoded in a one-byte-per-character fashion rather than the actual + multi-byte encoding. + + None of the standard non-modal encodings meet all of these +conditions. For example, EUC satisfies only (2) and (3), while +Shift-JIS and Big5 (not yet described) satisfy only (2). (All non-modal +encodings must satisfy (2), in order to be unambiguous.) + + +File: internals.info, Node: Internal Character Encoding, Prev: Internal String Encoding, Up: Internal Mule Encodings + +Internal Character Encoding +--------------------------- + +One 19-bit word represents a single character. The word is separated +into three fields: + + Bit number: 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + <------------> <------------------> <------------------> + Field: 1 2 3 + + Note that fields 2 and 3 hold 7 bits each, while field 1 holds 5 +bits. + + Character set Field 1 Field 2 Field 3 + ------------- ------- ------- ------- + ASCII 0 0 PC1 + range: (00 - 7F) + Control-1 0 1 PC1 + range: (00 - 1F) + Dimension-1 official 0 LB - 0x80 PC1 + range: (01 - 0D) (20 - 7F) + Dimension-1 private 0 LB - 0x80 PC1 + range: (20 - 6F) (20 - 7F) + Dimension-2 official LB - 0x8F PC1 PC2 + range: (01 - 0A) (20 - 7F) (20 - 7F) + Dimension-2 private LB - 0xE1 PC1 PC2 + range: (0F - 1E) (20 - 7F) (20 - 7F) + Composite 0x1F ? ? + + Note that character codes 0 - 255 are the same as the "binary +encoding" described above. + + +File: internals.info, Node: CCL, Prev: Internal Mule Encodings, Up: MULE Character Sets and Encodings + +CCL +=== + + CCL PROGRAM SYNTAX: + CCL_PROGRAM := (CCL_MAIN_BLOCK + [ CCL_EOF_BLOCK ]) + + CCL_MAIN_BLOCK := CCL_BLOCK + CCL_EOF_BLOCK := CCL_BLOCK + + CCL_BLOCK := STATEMENT | (STATEMENT [STATEMENT ...]) + STATEMENT := + SET | IF | BRANCH | LOOP | REPEAT | BREAK + | READ | WRITE + + SET := (REG = EXPRESSION) | (REG SELF_OP EXPRESSION) + | INT-OR-CHAR + + EXPRESSION := ARG | (EXPRESSION OP ARG) + + IF := (if EXPRESSION CCL_BLOCK CCL_BLOCK) + BRANCH := (branch EXPRESSION CCL_BLOCK [CCL_BLOCK ...]) + LOOP := (loop STATEMENT [STATEMENT ...]) + BREAK := (break) + REPEAT := (repeat) + | (write-repeat [REG | INT-OR-CHAR | string]) + | (write-read-repeat REG [INT-OR-CHAR | string | ARRAY]?) + READ := (read REG) | (read REG REG) + | (read-if REG ARITH_OP ARG CCL_BLOCK CCL_BLOCK) + | (read-branch REG CCL_BLOCK [CCL_BLOCK ...]) + WRITE := (write REG) | (write REG REG) + | (write INT-OR-CHAR) | (write STRING) | STRING + | (write REG ARRAY) + END := (end) + + REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 + ARG := REG | INT-OR-CHAR + OP := + | - | * | / | % | & | '|' | ^ | << | >> | <8 | >8 | // + | < | > | == | <= | >= | != + SELF_OP := + += | -= | *= | /= | %= | &= | '|=' | ^= | <<= | >>= + ARRAY := '[' INT-OR-CHAR ... ']' + INT-OR-CHAR := INT | CHAR + + MACHINE CODE: + + The machine code consists of a vector of 32-bit words. + The first such word specifies the start of the EOF section of the code; + this is the code executed to handle any stuff that needs to be done + (e.g. designating back to ASCII and left-to-right mode) after all + other encoded/decoded data has been written out. This is not used for + charset CCL programs. + + REGISTER: 0..7 -- referred by RRR or rrr + + OPERATOR BIT FIELD (27-bit): XXXXXXXXXXXXXXX RRR TTTTT + TTTTT (5-bit): operator type + RRR (3-bit): register number + XXXXXXXXXXXXXXXX (15-bit): + CCCCCCCCCCCCCCC: constant or address + 000000000000rrr: register number + + AAAA: 00000 + + 00001 - + 00010 * + 00011 / + 00100 % + 00101 & + 00110 | + 00111 ~ + + 01000 << + 01001 >> + 01010 <8 + 01011 >8 + 01100 // + 01101 not used + 01110 not used + 01111 not used + + 10000 < + 10001 > + 10010 == + 10011 <= + 10100 >= + 10101 != + + OPERATORS: TTTTT RRR XX.. + + SetCS: 00000 RRR C...C RRR = C...C + SetCL: 00001 RRR ..... RRR = c...c + c.............c + SetR: 00010 RRR ..rrr RRR = rrr + SetA: 00011 RRR ..rrr RRR = array[rrr] + C.............C size of array = C...C + c.............c contents = c...c + + Jump: 00100 000 c...c jump to c...c + JumpCond: 00101 RRR c...c if (!RRR) jump to c...c + WriteJump: 00110 RRR c...c Write1 RRR, jump to c...c + WriteReadJump: 00111 RRR c...c Write1, Read1 RRR, jump to c...c + WriteCJump: 01000 000 c...c Write1 C...C, jump to c...c + C...C + WriteCReadJump: 01001 RRR c...c Write1 C...C, Read1 RRR, + C.............C and jump to c...c + WriteSJump: 01010 000 c...c WriteS, jump to c...c + C.............C + S.............S + ... + WriteSReadJump: 01011 RRR c...c WriteS, Read1 RRR, jump to c...c + C.............C + S.............S + ... + WriteAReadJump: 01100 RRR c...c WriteA, Read1 RRR, jump to c...c + C.............C size of array = C...C + c.............c contents = c...c + ... + Branch: 01101 RRR C...C if (RRR >= 0 && RRR < C..) + c.............c branch to (RRR+1)th address + Read1: 01110 RRR ... read 1-byte to RRR + Read2: 01111 RRR ..rrr read 2-byte to RRR and rrr + ReadBranch: 10000 RRR C...C Read1 and Branch + c.............c + ... + Write1: 10001 RRR ..... write 1-byte RRR + Write2: 10010 RRR ..rrr write 2-byte RRR and rrr + WriteC: 10011 000 ..... write 1-char C...CC + C.............C + WriteS: 10100 000 ..... write C..-byte of string + C.............C + S.............S + ... + WriteA: 10101 RRR ..... write array[RRR] + C.............C size of array = C...C + c.............c contents = c...c + ... + End: 10110 000 ..... terminate the execution + + SetSelfCS: 10111 RRR C...C RRR AAAAA= C...C + ..........AAAAA + SetSelfCL: 11000 RRR ..... RRR AAAAA= c...c + c.............c + ..........AAAAA + SetSelfR: 11001 RRR ..Rrr RRR AAAAA= rrr + ..........AAAAA + SetExprCL: 11010 RRR ..Rrr RRR = rrr AAAAA c...c + c.............c + ..........AAAAA + SetExprR: 11011 RRR ..rrr RRR = rrr AAAAA Rrr + ............Rrr + ..........AAAAA + JumpCondC: 11100 RRR c...c if !(RRR AAAAA C..) jump to c...c + C.............C + ..........AAAAA + JumpCondR: 11101 RRR c...c if !(RRR AAAAA rrr) jump to c...c + ............rrr + ..........AAAAA + ReadJumpCondC: 11110 RRR c...c Read1 and JumpCondC + C.............C + ..........AAAAA + ReadJumpCondR: 11111 RRR c...c Read1 and JumpCondR + ............rrr + ..........AAAAA + + +File: internals.info, Node: The Lisp Reader and Compiler, Next: Lstreams, Prev: MULE Character Sets and Encodings, Up: Top + +The Lisp Reader and Compiler +**************************** + +Not yet documented. + + +File: internals.info, Node: Lstreams, Next: Consoles; Devices; Frames; Windows, Prev: The Lisp Reader and Compiler, Up: Top + +Lstreams +******** + +An "lstream" is an internal Lisp object that provides a generic +buffering stream implementation. Conceptually, you send data to the +stream or read data from the stream, not caring what's on the other end +of the stream. The other end could be another stream, a file +descriptor, a stdio stream, a fixed block of memory, a reallocating +block of memory, etc. The main purpose of the stream is to provide a +standard interface and to do buffering. Macros are defined to read or +write characters, so the calling functions do not have to worry about +blocking data together in order to achieve efficiency. + +* Menu: + +* Creating an Lstream:: Creating an lstream object. +* Lstream Types:: Different sorts of things that are streamed. +* Lstream Functions:: Functions for working with lstreams. +* Lstream Methods:: Creating new lstream types. + + +File: internals.info, Node: Creating an Lstream, Next: Lstream Types, Up: Lstreams + +Creating an Lstream +=================== + +Lstreams come in different types, depending on what is being interfaced +to. Although the primitive for creating new lstreams is +`Lstream_new()', generally you do not call this directly. Instead, you +call some type-specific creation function, which creates the lstream +and initializes it as appropriate for the particular type. + + All lstream creation functions take a MODE argument, specifying what +mode the lstream should be opened as. This controls whether the +lstream is for input and output, and optionally whether data should be +blocked up in units of MULE characters. Note that some types of +lstreams can only be opened for input; others only for output; and +others can be opened either way. #### Richard Mlynarik thinks that +there should be a strict separation between input and output streams, +and he's probably right. + + MODE is a string, one of + +`"r"' + Open for reading. + +`"w"' + Open for writing. + +`"rc"' + Open for reading, but "read" never returns partial MULE characters. + +`"wc"' + Open for writing, but never writes partial MULE characters. + + +File: internals.info, Node: Lstream Types, Next: Lstream Functions, Prev: Creating an Lstream, Up: Lstreams + +Lstream Types +============= + +stdio + +filedesc + +lisp-string + +fixed-buffer - Other reasonable uses of `unsigned int' and `unsigned long' are -representing non-quantities - e.g. bit-oriented flags and such. +resizing-buffer + +dynarr + +lisp-buffer + +print + +decoding + +encoding  -File: internals.info, Node: Coding for Mule, Next: Techniques for XEmacs Developers, Prev: Proper Use of Unsigned Types, Up: Rules When Writing New C Code +File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams + +Lstream Functions +================= -Coding for Mule + - Function: Lstream * Lstream_new (Lstream_implementation *IMP, const + char *MODE) + Allocate and return a new Lstream. This function is not really + meant to be called directly; rather, each stream type should + provide its own stream creation function, which creates the stream + and does any other necessary creation stuff (e.g. opening a file). + + - Function: void Lstream_set_buffering (Lstream *LSTR, + Lstream_buffering BUFFERING, int BUFFERING_SIZE) + Change the buffering of a stream. See `lstream.h'. By default the + buffering is `STREAM_BLOCK_BUFFERED'. + + - Function: int Lstream_flush (Lstream *LSTR) + Flush out any pending unwritten data in the stream. Clear any + buffered input data. Returns 0 on success, -1 on error. + + - Macro: int Lstream_putc (Lstream *STREAM, int C) + Write out one byte to the stream. This is a macro and so it is + very efficient. The C argument is only evaluated once but the + STREAM argument is evaluated more than once. Returns 0 on + success, -1 on error. + + - Macro: int Lstream_getc (Lstream *STREAM) + Read one byte from the stream. This is a macro and so it is very + efficient. The STREAM argument is evaluated more than once. + Return value is -1 for EOF or error. + + - Macro: void Lstream_ungetc (Lstream *STREAM, int C) + Push one byte back onto the input queue. This will be the next + byte read from the stream. Any number of bytes can be pushed back + and will be read in the reverse order they were pushed back--most + recent first. (This is necessary for consistency--if there are a + number of bytes that have been unread and I read and unread a + byte, it needs to be the first to be read again.) This is a macro + and so it is very efficient. The C argument is only evaluated + once but the STREAM argument is evaluated more than once. + + - Function: int Lstream_fputc (Lstream *STREAM, int C) + - Function: int Lstream_fgetc (Lstream *STREAM) + - Function: void Lstream_fungetc (Lstream *STREAM, int C) + Function equivalents of the above macros. + + - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t + SIZE) + Read SIZE bytes of DATA from the stream. Return the number of + bytes read. 0 means EOF. -1 means an error occurred and no bytes + were read. + + - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t + SIZE) + Write SIZE bytes of DATA to the stream. Return the number of + bytes written. -1 means an error occurred and no bytes were + written. + + - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t + SIZE) + Push back SIZE bytes of DATA onto the input queue. The next call + to `Lstream_read()' with the same size will read the same bytes + back. Note that this will be the case even if there is other + pending unread data. + + - Function: int Lstream_close (Lstream *STREAM) + Close the stream. All data will be flushed out. + + - Function: void Lstream_reopen (Lstream *STREAM) + Reopen a closed stream. This enables I/O on it again. This is not + meant to be called except from a wrapper routine that reinitializes + variables and such--the close routine may well have freed some + necessary storage structures, for example. + + - Function: void Lstream_rewind (Lstream *STREAM) + Rewind the stream to the beginning. + + +File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams + +Lstream Methods =============== - Although Mule support is not compiled by default in XEmacs, many -people are using it, and we consider it crucial that new code works -correctly with multibyte characters. This is not hard; it is only a -matter of following several simple user-interface guidelines. Even if -you never compile with Mule, with a little practice you will find it -quite easy to code Mule-correctly. - - Note that these guidelines are not necessarily tied to the current -Mule implementation; they are also a good idea to follow on the grounds -of code generalization for future I18N work. + - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char + *DATA, size_t SIZE) + Read some data from the stream's end and store it into DATA, which + can hold SIZE bytes. Return the number of bytes read. A return + value of 0 means no bytes can be read at this time. This may be + because of an EOF, or because there is a granularity greater than + one byte that the stream imposes on the returned data, and SIZE is + less than this granularity. (This will happen frequently for + streams that need to return whole characters, because + `Lstream_read()' calls the reader function repeatedly until it has + the number of bytes it wants or until 0 is returned.) The lstream + functions do not treat a 0 return as EOF or do anything special; + however, the calling function will interpret any 0 it gets back as + EOF. This will normally not happen unless the caller calls + `Lstream_read()' with a very small size. + + This function can be `NULL' if the stream is output-only. + + - Lstream Method: ssize_t writer (Lstream *STREAM, const unsigned char + *DATA, size_t SIZE) + Send some data to the stream's end. Data to be sent is in DATA + and is SIZE bytes. Return the number of bytes sent. This + function can send and return fewer bytes than is passed in; in that + case, the function will just be called again until there is no + data left or 0 is returned. A return value of 0 means that no + more data can be currently stored, but there is no error; the data + will be squirreled away until the writer can accept data. (This is + useful, e.g., if you're dealing with a non-blocking file + descriptor and are getting `EWOULDBLOCK' errors.) This function + can be `NULL' if the stream is input-only. + + - Lstream Method: int rewinder (Lstream *STREAM) + Rewind the stream. If this is `NULL', the stream is not seekable. + + - Lstream Method: int seekable_p (Lstream *STREAM) + Indicate whether this stream is seekable--i.e. it can be rewound. + This method is ignored if the stream does not have a rewind + method. If this method is not present, the result is determined + by whether a rewind method is present. + + - Lstream Method: int flusher (Lstream *STREAM) + Perform any additional operations necessary to flush the data in + this stream. + + - Lstream Method: int pseudo_closer (Lstream *STREAM) + + - Lstream Method: int closer (Lstream *STREAM) + Perform any additional operations necessary to close this stream + down. May be `NULL'. This function is called when + `Lstream_close()' is called or when the stream is + garbage-collected. When this function is called, all pending data + in the stream will already have been written out. + + - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void + (*MARKFUN) (Lisp_Object)) + Mark this object for garbage collection. Same semantics as a + standard `Lisp_Object' marker. This function can be `NULL'. + + +File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top + +Consoles; Devices; Frames; Windows +********************************** * Menu: -* Character-Related Data Types:: -* Working With Character and Byte Positions:: -* Conversion to and from External Data:: -* General Guidelines for Writing Mule-Aware Code:: -* An Example of Mule-Aware Code:: +* Introduction to Consoles; Devices; Frames; Windows:: +* Point:: +* Window Hierarchy:: +* The Window Object:: + + +File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Up: Consoles; Devices; Frames; Windows + +Introduction to Consoles; Devices; Frames; Windows +================================================== + +A window-system window that you see on the screen is called a "frame" +in Emacs terminology. Each frame is subdivided into one or more +non-overlapping panes, called (confusingly) "windows". Each window +displays the text of a buffer in it. (See above on Buffers.) Note that +buffers and windows are independent entities: Two or more windows can +be displaying the same buffer (potentially in different locations), and +a buffer can be displayed in no windows. + + A single display screen that contains one or more frames is called a +"display". Under most circumstances, there is only one display. +However, more than one display can exist, for example if you have a +"multi-headed" console, i.e. one with a single keyboard but multiple +displays. (Typically in such a situation, the various displays act like +one large display, in that the mouse is only in one of them at a time, +and moving the mouse off of one moves it into another.) In some cases, +the different displays will have different characteristics, e.g. one +color and one mono. + + XEmacs can display frames on multiple displays. It can even deal +simultaneously with frames on multiple keyboards (called "consoles" in +XEmacs terminology). Here is one case where this might be useful: You +are using XEmacs on your workstation at work, and leave it running. +Then you go home and dial in on a TTY line, and you can use the +already-running XEmacs process to display another frame on your local +TTY. + + Thus, there is a hierarchy console -> display -> frame -> window. +There is a separate Lisp object type for each of these four concepts. +Furthermore, there is logically a "selected console", "selected +display", "selected frame", and "selected window". Each of these +objects is distinguished in various ways, such as being the default +object for various functions that act on objects of that type. Note +that every containing object remembers the "selected" object among the +objects that it contains: e.g. not only is there a selected window, but +every frame remembers the last window in it that was selected, and +changing the selected frame causes the remembered window within it to +become the selected window. Similar relationships apply for consoles +to devices and devices to frames. + + +File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows + +Point +===== + +Recall that every buffer has a current insertion position, called +"point". Now, two or more windows may be displaying the same buffer, +and the text cursor in the two windows (i.e. `point') can be in two +different places. You may ask, how can that be, since each buffer has +only one value of `point'? The answer is that each window also has a +value of `point' that is squirreled away in it. There is only one +selected window, and the value of "point" in that buffer corresponds to +that window. When the selected window is changed from one window to +another displaying the same buffer, the old value of `point' is stored +into the old window's "point" and the value of `point' from the new +window is retrieved and made the value of `point' in the buffer. This +means that `window-point' for the selected window is potentially +inaccurate, and if you want to retrieve the correct value of `point' +for a window, you must special-case on the selected window and retrieve +the buffer's point instead. This is related to why +`save-window-excursion' does not save the selected window's value of +`point'. + + +File: internals.info, Node: Window Hierarchy, Next: The Window Object, Prev: Point, Up: Consoles; Devices; Frames; Windows + +Window Hierarchy +================ + +If a frame contains multiple windows (panes), they are always created +by splitting an existing window along the horizontal or vertical axis. +Terminology is a bit confusing here: to "split a window horizontally" +means to create two side-by-side windows, i.e. to make a _vertical_ cut +in a window. Likewise, to "split a window vertically" means to create +two windows, one above the other, by making a _horizontal_ cut. + + If you split a window and then split again along the same axis, you +will end up with a number of panes all arranged along the same axis. +The precise way in which the splits were made should not be important, +and this is reflected internally. Internally, all windows are arranged +in a tree, consisting of two types of windows, "combination" windows +(which have children, and are covered completely by those children) and +"leaf" windows, which have no children and are visible. Every +combination window has two or more children, all arranged along the same +axis. There are (logically) two subtypes of windows, depending on +whether their children are horizontally or vertically arrayed. There is +always one root window, which is either a leaf window (if the frame +contains only one window) or a combination window (if the frame contains +more than one window). In the latter case, the root window will have +two or more children, either horizontally or vertically arrayed, and +each of those children will be either a leaf window or another +combination window. + + Here are some rules: + + 1. Horizontal combination windows can never have children that are + horizontal combination windows; same for vertical. + + 2. Only leaf windows can be split (obviously) and this splitting does + one of two things: (a) turns the leaf window into a combination + window and creates two new leaf children, or (b) turns the leaf + window into one of the two new leaves and creates the other leaf. + Rule (1) dictates which of these two outcomes happens. + + 3. Every combination window must have at least two children. + + 4. Leaf windows can never become combination windows. They can be + deleted, however. If this results in a violation of (3), the + parent combination window also gets deleted. + + 5. All functions that accept windows must be prepared to accept + combination windows, and do something sane (e.g. signal an error + if so). Combination windows _do_ escape to the Lisp level. + + 6. All windows have three fields governing their contents: these are + "hchild" (a list of horizontally-arrayed children), "vchild" (a + list of vertically-arrayed children), and "buffer" (the buffer + contained in a leaf window). Exactly one of these will be + non-`nil'. Remember that "horizontally-arrayed" means + "side-by-side" and "vertically-arrayed" means "one above the + other". + + 7. Leaf windows also have markers in their `start' (the first buffer + position displayed in the window) and `pointm' (the window's + stashed value of `point'--see above) fields, while combination + windows have `nil' in these fields. + + 8. The list of children for a window is threaded through the `next' + and `prev' fields of each child window. + + 9. *Deleted windows can be undeleted*. This happens as a result of + restoring a window configuration, and is unlike frames, displays, + and consoles, which, once deleted, can never be restored. + Deleting a window does nothing except set a special `dead' bit to + 1 and clear out the `next', `prev', `hchild', and `vchild' fields, + for GC purposes. + + 10. Most frames actually have two top-level windows--one for the + minibuffer and one (the "root") for everything else. The modeline + (if present) separates these two. The `next' field of the root + points to the minibuffer, and the `prev' field of the minibuffer + points to the root. The other `next' and `prev' fields are `nil', + and the frame points to both of these windows. Minibuffer-less + frames have no minibuffer window, and the `next' and `prev' of the + root window are `nil'. Minibuffer-only frames have no root + window, and the `next' of the minibuffer window is `nil' but the + `prev' points to itself. (#### This is an artifact that should be + fixed.) + + +File: internals.info, Node: The Window Object, Prev: Window Hierarchy, Up: Consoles; Devices; Frames; Windows + +The Window Object +================= + +Windows have the following accessible fields: + +`frame' + The frame that this window is on. + +`mini_p' + Non-`nil' if this window is a minibuffer window. + +`buffer' + The buffer that the window is displaying. This may change often + during the life of the window. + +`dedicated' + Non-`nil' if this window is dedicated to its buffer. + +`pointm' + This is the value of point in the current buffer when this window + is selected; when it is not selected, it retains its previous + value. + +`start' + The position in the buffer that is the first character to be + displayed in the window. + +`force_start' + If this flag is non-`nil', it says that the window has been + scrolled explicitly by the Lisp program. This affects what the + next redisplay does if point is off the screen: instead of + scrolling the window to show the text around point, it moves point + to a location that is on the screen. + +`last_modified' + The `modified' field of the window's buffer, as of the last time a + redisplay completed in this window. + +`last_point' + The buffer's value of point, as of the last time a redisplay + completed in this window. + +`left' + This is the left-hand edge of the window, measured in columns. + (The leftmost column on the screen is column 0.) + +`top' + This is the top edge of the window, measured in lines. (The top + line on the screen is line 0.) + +`height' + The height of the window, measured in lines. + +`width' + The width of the window, measured in columns. + +`next' + This is the window that is the next in the chain of siblings. It + is `nil' in a window that is the rightmost or bottommost of a + group of siblings. + +`prev' + This is the window that is the previous in the chain of siblings. + It is `nil' in a window that is the leftmost or topmost of a group + of siblings. + +`parent' + Internally, XEmacs arranges windows in a tree; each group of + siblings has a parent window whose area includes all the siblings. + This field points to a window's parent. + + Parent windows do not display buffers, and play little role in + display except to shape their child windows. Emacs Lisp programs + usually have no access to the parent windows; they operate on the + windows at the leaves of the tree, which actually display buffers. + +`hscroll' + This is the number of columns that the display in the window is + scrolled horizontally to the left. Normally, this is 0. + +`use_time' + This is the last time that the window was selected. The function + `get-lru-window' uses this field. + +`display_table' + The window's display table, or `nil' if none is specified for it. + +`update_mode_line' + Non-`nil' means this window's mode line needs to be updated. + +`base_line_number' + The line number of a certain position in the buffer, or `nil'. + This is used for displaying the line number of point in the mode + line. + +`base_line_pos' + The position in the buffer for which the line number is known, or + `nil' meaning none is known. + +`region_showing' + If the region (or part of it) is highlighted in this window, this + field holds the mark position that made one end of that region. + Otherwise, this field is `nil'. + + +File: internals.info, Node: The Redisplay Mechanism, Next: Extents, Prev: Consoles; Devices; Frames; Windows, Up: Top + +The Redisplay Mechanism +*********************** + +The redisplay mechanism is one of the most complicated sections of +XEmacs, especially from a conceptual standpoint. This is doubly so +because, unlike for the basic aspects of the Lisp interpreter, the +computer science theories of how to efficiently handle redisplay are not +well-developed. + + When working with the redisplay mechanism, remember the Golden Rules +of Redisplay: + + 1. It Is Better To Be Correct Than Fast. + + 2. Thou Shalt Not Run Elisp From Within Redisplay. + + 3. It Is Better To Be Fast Than Not To Be. + +* Menu: + +* Critical Redisplay Sections:: +* Line Start Cache:: +* Redisplay Piece by Piece:: + + +File: internals.info, Node: Critical Redisplay Sections, Next: Line Start Cache, Up: The Redisplay Mechanism + +Critical Redisplay Sections +=========================== + +Within this section, we are defenseless and assume that the following +cannot happen: + + 1. garbage collection + + 2. Lisp code evaluation + + 3. frame size changes + + We ensure (3) by calling `hold_frame_size_changes()', which will +cause any pending frame size changes to get put on hold till after the +end of the critical section. (1) follows automatically if (2) is met. +#### Unfortunately, there are some places where Lisp code can be called +within this section. We need to remove them. + + If `Fsignal()' is called during this critical section, we will +`abort()'. + + If garbage collection is called during this critical section, we +simply return. #### We should abort instead. + + #### If a frame-size change does occur we should probably actually +be preempting redisplay. + + +File: internals.info, Node: Line Start Cache, Next: Redisplay Piece by Piece, Prev: Critical Redisplay Sections, Up: The Redisplay Mechanism + +Line Start Cache +================ + +The traditional scrolling code in Emacs breaks in a variable height +world. It depends on the key assumption that the number of lines that +can be displayed at any given time is fixed. This led to a complete +separation of the scrolling code from the redisplay code. In order to +fully support variable height lines, the scrolling code must actually be +tightly integrated with redisplay. Only redisplay can determine how +many lines will be displayed on a screen for any given starting point. + + What is ideally wanted is a complete list of the starting buffer +position for every possible display line of a buffer along with the +height of that display line. Maintaining such a full list would be very +expensive. We settle for having it include information for all areas +which we happen to generate anyhow (i.e. the region currently being +displayed) and for those areas we need to work with. + + In order to ensure that the cache accurately represents what +redisplay would actually show, it is necessary to invalidate it in many +situations. If the buffer changes, the starting positions may no longer +be correct. If a face or an extent has changed then the line heights +may have altered. These events happen frequently enough that the cache +can end up being constantly disabled. With this potentially constant +invalidation when is the cache ever useful? + + Even if the cache is invalidated before every single usage, it is +necessary. Scrolling often requires knowledge about display lines which +are actually above or below the visible region. The cache provides a +convenient light-weight method of storing this information for multiple +display regions. This knowledge is necessary for the scrolling code to +always obey the First Golden Rule of Redisplay. + + If the cache already contains all of the information that the +scrolling routines happen to need so that it doesn't have to go +generate it, then we are able to obey the Third Golden Rule of +Redisplay. The first thing we do to help out the cache is to always +add the displayed region. This region had to be generated anyway, so +the cache ends up getting the information basically for free. In those +cases where a user is simply scrolling around viewing a buffer there is +a high probability that this is sufficient to always provide the needed +information. The second thing we can do is be smart about invalidating +the cache. + + TODO--Be smart about invalidating the cache. Potential places: + + * Insertions at end-of-line which don't cause line-wraps do not + alter the starting positions of any display lines. These types of + buffer modifications should not invalidate the cache. This is + actually a large optimization for redisplay speed as well. + + * Buffer modifications frequently only affect the display of lines + at and below where they occur. In these situations we should only + invalidate the part of the cache starting at where the + modification occurs. + + In case you're wondering, the Second Golden Rule of Redisplay is not +applicable. + + +File: internals.info, Node: Redisplay Piece by Piece, Prev: Line Start Cache, Up: The Redisplay Mechanism + +Redisplay Piece by Piece +======================== + +As you can begin to see redisplay is complex and also not well +documented. Chuck no longer works on XEmacs so this section is my take +on the workings of redisplay. + + Redisplay happens in three phases: + + 1. Determine desired display in area that needs redisplay. + Implemented by `redisplay.c' + + 2. Compare desired display with current display Implemented by + `redisplay-output.c' + + 3. Output changes Implemented by `redisplay-output.c', + `redisplay-x.c', `redisplay-msw.c' and `redisplay-tty.c' + + Steps 1 and 2 are device-independent and relatively complex. Step 3 +is mostly device-dependent. + + Determining the desired display + + Display attributes are stored in `display_line' structures. Each +`display_line' consists of a set of `display_block''s and each +`display_block' contains a number of `rune''s. Generally dynarr's of +`display_line''s are held by each window representing the current +display and the desired display. + + The `display_line' structures are tightly tied to buffers which +presents a problem for redisplay as this connection is bogus for the +modeline. Hence the `display_line' generation routines are duplicated +for generating the modeline. This means that the modeline display code +has many bugs that the standard redisplay code does not. + + The guts of `display_line' generation are in `create_text_block', +which creates a single display line for the desired locale. This +incrementally parses the characters on the current line and generates +redisplay structures for each. + + Gutter redisplay is different. Because the data to display is stored +in a string we cannot use `create_text_block'. Instead we use +`create_text_string_block' which performs the same function as +`create_text_block' but for strings. Many of the complexities of +`create_text_block' to do with cursor handling and selective display +have been removed. + + +File: internals.info, Node: Extents, Next: Faces, Prev: The Redisplay Mechanism, Up: Top + +Extents +******* + +* Menu: + +* Introduction to Extents:: Extents are ranges over text, with properties. +* Extent Ordering:: How extents are ordered internally. +* Format of the Extent Info:: The extent information in a buffer or string. +* Zero-Length Extents:: A weird special case. +* Mathematics of Extent Ordering:: A rigorous foundation. +* Extent Fragments:: Cached information useful for redisplay. + + +File: internals.info, Node: Introduction to Extents, Next: Extent Ordering, Up: Extents + +Introduction to Extents +======================= + +Extents are regions over a buffer, with a start and an end position +denoting the region of the buffer included in the extent. In addition, +either end can be closed or open, meaning that the endpoint is or is +not logically included in the extent. Insertion of a character at a +closed endpoint causes the character to go inside the extent; insertion +at an open endpoint causes the character to go outside. + + Extent endpoints are stored using memory indices (see `insdel.c'), +to minimize the amount of adjusting that needs to be done when +characters are inserted or deleted. + + (Formerly, extent endpoints at the gap could be either before or +after the gap, depending on the open/closedness of the endpoint. The +intent of this was to make it so that insertions would automatically go +inside or out of extents as necessary with no further work needing to +be done. It didn't work out that way, however, and just ended up +complexifying and buggifying all the rest of the code.) + + +File: internals.info, Node: Extent Ordering, Next: Format of the Extent Info, Prev: Introduction to Extents, Up: Extents + +Extent Ordering +=============== + +Extents are compared using memory indices. There are two orderings for +extents and both orders are kept current at all times. The normal or +"display" order is as follows: + + Extent A is ``less than'' extent B, + that is, earlier in the display order, + if: A-start < B-start, + or if: A-start = B-start, and A-end > B-end + + So if two extents begin at the same position, the larger of them is +the earlier one in the display order (`EXTENT_LESS' is true). + + For the e-order, the same thing holds: + + Extent A is ``less than'' extent B in e-order, + that is, later in the buffer, + if: A-end < B-end, + or if: A-end = B-end, and A-start > B-start + + So if two extents end at the same position, the smaller of them is +the earlier one in the e-order (`EXTENT_E_LESS' is true). + + The display order and the e-order are complementary orders: any +theorem about the display order also applies to the e-order if you swap +all occurrences of "display order" and "e-order", "less than" and +"greater than", and "extent start" and "extent end". + + +File: internals.info, Node: Format of the Extent Info, Next: Zero-Length Extents, Prev: Extent Ordering, Up: Extents + +Format of the Extent Info +========================= + +An extent-info structure consists of a list of the buffer or string's +extents and a "stack of extents" that lists all of the extents over a +particular position. The stack-of-extents info is used for +optimization purposes--it basically caches some info that might be +expensive to compute. Certain otherwise hard computations are easy +given the stack of extents over a particular position, and if the stack +of extents over a nearby position is known (because it was calculated +at some prior point in time), it's easy to move the stack of extents to +the proper position. + + Given that the stack of extents is an optimization, and given that +it requires memory, a string's stack of extents is wiped out each time +a garbage collection occurs. Therefore, any time you retrieve the +stack of extents, it might not be there. If you need it to be there, +use the `_force' version. + + Similarly, a string may or may not have an extent_info structure. +(Generally it won't if there haven't been any extents added to the +string.) So use the `_force' version if you need the extent_info +structure to be there. + + A list of extents is maintained as a double gap array: one gap array +is ordered by start index (the "display order") and the other is +ordered by end index (the "e-order"). Note that positions in an extent +list should logically be conceived of as referring _to_ a particular +extent (as is the norm in programs) rather than sitting between two +extents. Note also that callers of these functions should not be aware +of the fact that the extent list is implemented as an array, except for +the fact that positions are integers (this should be generalized to +handle integers and linked list equally well). + + +File: internals.info, Node: Zero-Length Extents, Next: Mathematics of Extent Ordering, Prev: Format of the Extent Info, Up: Extents + +Zero-Length Extents +=================== + +Extents can be zero-length, and will end up that way if their endpoints +are explicitly set that way or if their detachable property is `nil' +and all the text in the extent is deleted. (The exception is open-open +zero-length extents, which are barred from existing because there is no +sensible way to define their properties. Deletion of the text in an +open-open extent causes it to be converted into a closed-open extent.) +Zero-length extents are primarily used to represent annotations, and +behave as follows: + + 1. Insertion at the position of a zero-length extent expands the + extent if both endpoints are closed; goes after the extent if it + is closed-open; and goes before the extent if it is open-closed. + + 2. Deletion of a character on a side of a zero-length extent whose + corresponding endpoint is closed causes the extent to be detached + if it is detachable; if the extent is not detachable or the + corresponding endpoint is open, the extent remains in the buffer, + moving as necessary. + + Note that closed-open, non-detachable zero-length extents behave +exactly like markers and that open-closed, non-detachable zero-length +extents behave like the "point-type" marker in Mule. + + +File: internals.info, Node: Mathematics of Extent Ordering, Next: Extent Fragments, Prev: Zero-Length Extents, Up: Extents + +Mathematics of Extent Ordering +============================== + +The extents in a buffer are ordered by "display order" because that is +that order that the redisplay mechanism needs to process them in. The +e-order is an auxiliary ordering used to facilitate operations over +extents. The operations that can be performed on the ordered list of +extents in a buffer are + + 1. Locate where an extent would go if inserted into the list. + + 2. Insert an extent into the list. + + 3. Remove an extent from the list. + + 4. Map over all the extents that overlap a range. + + (4) requires being able to determine the first and last extents that +overlap a range. + + NOTE: "overlap" is used as follows: + + * two ranges overlap if they have at least one point in common. + Whether the endpoints are open or closed makes a difference here. + + * a point overlaps a range if the point is contained within the + range; this is equivalent to treating a point P as the range [P, + P]. + + * In the case of an _extent_ overlapping a point or range, the extent + is normally treated as having closed endpoints. This applies + consistently in the discussion of stacks of extents and such below. + Note that this definition of overlap is not necessarily consistent + with the extents that `map-extents' maps over, since `map-extents' + sometimes pays attention to whether the endpoints of an extents + are open or closed. But for our purposes, it greatly simplifies + things to treat all extents as having closed endpoints. + + First, define >, <, <=, etc. as applied to extents to mean +comparison according to the display order. Comparison between an +extent E and an index I means comparison between E and the range [I, I]. + + Also define e>, e<, e<=, etc. to mean comparison according to the +e-order. + + For any range R, define R(0) to be the starting index of the range +and R(1) to be the ending index of the range. + + For any extent E, define E(next) to be the extent directly following +E, and E(prev) to be the extent directly preceding E. Assume E(next) +and E(prev) can be determined from E in constant time. (This is +because we store the extent list as a doubly linked list.) + + Similarly, define E(e-next) and E(e-prev) to be the extents directly +following and preceding E in the e-order. + + Now: + + Let R be a range. Let F be the first extent overlapping R. Let L +be the last extent overlapping R. + + Theorem 1: R(1) lies between L and L(next), i.e. L <= R(1) < L(next). + + This follows easily from the definition of display order. The basic +reason that this theorem applies is that the display order sorts by +increasing starting index. + + Therefore, we can determine L just by looking at where we would +insert R(1) into the list, and if we know F and are moving forward over +extents, we can easily determine when we've hit L by comparing the +extent we're at to R(1). + + Theorem 2: F(e-prev) e< [1, R(0)] e<= F. + + This is the analog of Theorem 1, and applies because the e-order +sorts by increasing ending index. + + Therefore, F can be found in the same amount of time as operation +(1), i.e. the time that it takes to locate where an extent would go if +inserted into the e-order list. + + If the lists were stored as balanced binary trees, then operation (1) +would take logarithmic time, which is usually quite fast. However, +currently they're stored as simple doubly-linked lists, and instead we +do some caching to try to speed things up. + + Define a "stack of extents" (or "SOE") as the set of extents +(ordered in the display order) that overlap an index I, together with +the SOE's "previous" extent, which is an extent that precedes I in the +e-order. (Hopefully there will not be very many extents between I and +the previous extent.) + + Now: + + Let I be an index, let S be the stack of extents on I, let F be the +first extent in S, and let P be S's previous extent. + + Theorem 3: The first extent in S is the first extent that overlaps +any range [I, J]. + + Proof: Any extent that overlaps [I, J] but does not include I must +have a start index > I, and thus be greater than any extent in S. + + Therefore, finding the first extent that overlaps a range R is the +same as finding the first extent that overlaps R(0). + + Theorem 4: Let I2 be an index such that I2 > I, and let F2 be the +first extent that overlaps I2. Then, either F2 is in S or F2 is +greater than any extent in S. + + Proof: If F2 does not include I then its start index is greater than +I and thus it is greater than any extent in S, including F. Otherwise, +F2 includes I and thus is in S, and thus F2 >= F. + + +File: internals.info, Node: Extent Fragments, Prev: Mathematics of Extent Ordering, Up: Extents + +Extent Fragments +================ + +Imagine that the buffer is divided up into contiguous, non-overlapping +"runs" of text such that no extent starts or ends within a run (extents +that abut the run don't count). + + An extent fragment is a structure that holds data about the run that +contains a particular buffer position (if the buffer position is at the +junction of two runs, the run after the position is used)--the +beginning and end of the run, a list of all of the extents in that run, +the "merged face" that results from merging all of the faces +corresponding to those extents, the begin and end glyphs at the +beginning of the run, etc. This is the information that redisplay needs +in order to display this run. + + Extent fragments have to be very quick to update to a new buffer +position when moving linearly through the buffer. They rely on the +stack-of-extents code, which does the heavy-duty algorithmic work of +determining which extents overly a particular position. + + +File: internals.info, Node: Faces, Next: Glyphs, Prev: Extents, Up: Top + +Faces +***** + +Not yet documented. + + +File: internals.info, Node: Glyphs, Next: Specifiers, Prev: Faces, Up: Top + +Glyphs +****** + +Glyphs are graphical elements that can be displayed in XEmacs buffers or +gutters. We use the term graphical element here in the broadest possible +sense since glyphs can be as mundane as text or as arcane as a native +tab widget. + + In XEmacs, glyphs represent the uninstantiated state of graphical +elements, i.e. they hold all the information necessary to produce an +image on-screen but the image need not exist at this stage, and multiple +screen images can be instantiated from a single glyph. + + Glyphs are lazily instantiated by calling one of the glyph +functions. This usually occurs within redisplay when `Fglyph_height' is +called. Instantiation causes an image-instance to be created and +cached. This cache is on a per-device basis for all glyphs except +widget-glyphs, and on a per-window basis for widgets-glyphs. The +caching is done by `image_instantiate' and is necessary because it is +generally possible to display an image-instance in multiple domains. +For instance if we create a Pixmap, we can actually display this on +multiple windows - even though we only need a single Pixmap instance to +do this. If caching wasn't done then it would be necessary to create +image-instances for every displayable occurrence of a glyph - and every +usage - and this would be extremely memory and cpu intensive. + + Widget-glyphs (a.k.a native widgets) are not cached in this way. +This is because widget-glyph image-instances on screen are toolkit +windows, and thus cannot be reused in multiple XEmacs domains. Thus +widget-glyphs are cached on an XEmacs window basis. + + Any action on a glyph first consults the cache before actually +instantiating a widget. + +Glyph Instantiation +=================== + +Glyph instantiation is a hairy topic and requires some explanation. The +guts of glyph instantiation is contained within `image_instantiate'. A +glyph contains an image which is a specifier. When a glyph function - +for instance `Fglyph_height' - asks for a property of the glyph that +can only be determined from its instantiated state, then the glyph +image is instantiated and an image instance created. The instantiation +process is governed by the specifier code and goes through a series of +steps: + + * Validation. Instantiation of image instances happens dynamically - + often within the guts of redisplay. Thus it is often not feasible + to catch instantiator errors at instantiation time. Instead the + instantiator is validated at the time it is added to the image + specifier. This function is defined by `image_validate' and at a + simple level validates keyword value pairs. + + * Duplication. The specifier code by default takes a copy of the + instantiator. This is reasonable for most specifiers but in the + case of widget-glyphs can be problematic, since some of the + properties in the instantiator - for instance callbacks - could + cause infinite recursion in the copying process. Thus the image + code defines a function - `image_copy_instantiator' - which will + selectively copy values. This is controlled by the way that a + keyword is defined either using `IIFORMAT_VALID_KEYWORD' or + `IIFORMAT_VALID_NONCOPY_KEYWORD'. Note that the image caching and + redisplay code relies on instantiator copying to ensure that + current and new instantiators are actually different rather than + referring to the same thing. + + * Normalization. Once the instantiator has been copied it must be + converted into a form that is viable at instantiation time. This + can involve no changes at all, but typically involves things like + converting file names to the actual data. This function is defined + by `image_going_to_add' and `normalize_image_instantiator'. + + * Instantiation. When an image instance is actually required for + display it is instantiated using `image_instantiate'. This + involves calling instantiate methods that are specific to the type + of image being instantiated. + + The final instantiation phase also involves a number of steps. In +order to understand these we need to describe a number of concepts. + + An image is instantiated in a "domain", where a domain can be any +one of a device, frame, window or image-instance. The domain gives the +image-instance context and identity and properties that affect the +appearance of the image-instance may be different for the same glyph +instantiated in different domains. An example is the face used to +display the image-instance. + + Although an image is instantiated in a particular domain the +instantiation domain is not necessarily the domain in which the +image-instance is cached. For example a pixmap can be instantiated in a +window be actually be cached on a per-device basis. The domain in which +the image-instance is actually cached is called the "governing-domain". +A governing-domain is currently either a device or a window. +Widget-glyphs and text-glyphs have a window as a governing-domain, all +other image-instances have a device as the governing-domain. The +governing domain for an image-instance is determined using the +governing_domain image-instance method. + +Widget-Glyphs +============= + +Widget-Glyphs in the MS-Windows Environment +=========================================== + +To Do + +Widget-Glyphs in the X Environment +================================== + +Widget-glyphs under X make heavy use of lwlib (*note Lucid Widget +Library::) for manipulating the native toolkit objects. This is +primarily so that different toolkits can be supported for +widget-glyphs, just as they are supported for features such as menubars +etc. + + Lwlib is extremely poorly documented and quite hairy so here is my +understanding of what goes on. + + Lwlib maintains a set of widget_instances which mirror the +hierarchical state of Xt widgets. I think this is so that widgets can +be updated and manipulated generically by the lwlib library. For +instance update_one_widget_instance can cope with multiple types of +widget and multiple types of toolkit. Each element in the widget +hierarchy is updated from its corresponding widget_instance by walking +the widget_instance tree recursively. + + This has desirable properties such as lw_modify_all_widgets which is +called from `glyphs-x.c' and updates all the properties of a widget +without having to know what the widget is or what toolkit it is from. +Unfortunately this also has hairy properties such as making the lwlib +code quite complex. And of course lwlib has to know at some level what +the widget is and how to set its properties. + + +File: internals.info, Node: Specifiers, Next: Menus, Prev: Glyphs, Up: Top + +Specifiers +********** + +Not yet documented. + + +File: internals.info, Node: Menus, Next: Subprocesses, Prev: Specifiers, Up: Top + +Menus +***** + +A menu is set by setting the value of the variable `current-menubar' +(which may be buffer-local) and then calling `set-menubar-dirty-flag' +to signal a change. This will cause the menu to be redrawn at the next +redisplay. The format of the data in `current-menubar' is described in +`menubar.c'. + + Internally the data in current-menubar is parsed into a tree of +`widget_value's' (defined in `lwlib.h'); this is accomplished by the +recursive function `menu_item_descriptor_to_widget_value()', called by +`compute_menubar_data()'. Such a tree is deallocated using +`free_widget_value()'. + + `update_screen_menubars()' is one of the external entry points. +This checks to see, for each screen, if that screen's menubar needs to +be updated. This is the case if + + 1. `set-menubar-dirty-flag' was called since the last redisplay. + (This function sets the C variable menubar_has_changed.) + + 2. The buffer displayed in the screen has changed. + + 3. The screen has no menubar currently displayed. + + `set_screen_menubar()' is called for each such screen. This +function calls `compute_menubar_data()' to create the tree of +widget_value's, then calls `lw_create_widget()', +`lw_modify_all_widgets()', and/or `lw_destroy_all_widgets()' to create +the X-Toolkit widget associated with the menu. + + `update_psheets()', the other external entry point, actually changes +the menus being displayed. It uses the widgets fixed by +`update_screen_menubars()' and calls various X functions to ensure that +the menus are displayed properly. + + The menubar widget is set up so that `pre_activate_callback()' is +called when the menu is first selected (i.e. mouse button goes down), +and `menubar_selection_callback()' is called when an item is selected. +`pre_activate_callback()' calls the function in activate-menubar-hook, +which can change the menubar (this is described in `menubar.c'). If +the menubar is changed, `set_screen_menubars()' is called. +`menubar_selection_callback()' enqueues a menu event, putting in it a +function to call (either `eval' or `call-interactively') and its +argument, which is the callback function or form given in the menu's +description. + + +File: internals.info, Node: Subprocesses, Next: Interface to the X Window System, Prev: Menus, Up: Top + +Subprocesses +************ + +The fields of a process are: + +`name' + A string, the name of the process. + +`command' + A list containing the command arguments that were used to start + this process. + +`filter' + A function used to accept output from the process instead of a + buffer, or `nil'. + +`sentinel' + A function called whenever the process receives a signal, or `nil'. + +`buffer' + The associated buffer of the process. + +`pid' + An integer, the Unix process ID. + +`childp' + A flag, non-`nil' if this is really a child process. It is `nil' + for a network connection. + +`mark' + A marker indicating the position of the end of the last output + from this process inserted into the buffer. This is often but not + always the end of the buffer. + +`kill_without_query' + If this is non-`nil', killing XEmacs while this process is still + running does not ask for confirmation about killing the process. + +`raw_status_low' +`raw_status_high' + These two fields record 16 bits each of the process status + returned by the `wait' system call. + +`status' + The process status, as `process-status' should return it. + +`tick' +`update_tick' + If these two fields are not equal, a change in the status of the + process needs to be reported, either by running the sentinel or by + inserting a message in the process buffer. + +`pty_flag' + Non-`nil' if communication with the subprocess uses a PTY; `nil' + if it uses a pipe. + +`infd' + The file descriptor for input from the process. + +`outfd' + The file descriptor for output to the process. + +`subtty' + The file descriptor for the terminal that the subprocess is using. + (On some systems, there is no need to record this, so the value is + `-1'.) + +`tty_name' + The name of the terminal that the subprocess is using, or `nil' if + it is using pipes. + + +File: internals.info, Node: Interface to the X Window System, Next: Index, Prev: Subprocesses, Up: Top + +Interface to the X Window System +******************************** + +Mostly undocumented. + +* Menu: + +* Lucid Widget Library:: An interface to various widget sets. + + +File: internals.info, Node: Lucid Widget Library, Up: Interface to the X Window System + +Lucid Widget Library +==================== + +Lwlib is extremely poorly documented and quite hairy. The author(s) +blame that on X, Xt, and Motif, with some justice, but also sufficient +hypocrisy to avoid drawing the obvious conclusion about their own work. + + The Lucid Widget Library is composed of two more or less independent +pieces. The first, as the name suggests, is a set of widgets. These +widgets are intended to resemble and improve on widgets provided in the +Motif toolkit but not in the Athena widgets, including menubars and +scrollbars. Recent additions by Andy Piper integrate some "modern" +widgets by Edward Falk, including checkboxes, radio buttons, progress +gauges, and index tab controls (aka notebooks). + + The second piece of the Lucid widget library is a generic interface +to several toolkits for X (including Xt, the Athena widget set, and +Motif, as well as the Lucid widgets themselves) so that core XEmacs +code need not know which widget set has been used to build the +graphical user interface. + +* Menu: + +* Generic Widget Interface:: The lwlib generic widget interface. +* Scrollbars:: +* Menubars:: +* Checkboxes and Radio Buttons:: +* Progress Bars:: +* Tab Controls:: + + +File: internals.info, Node: Generic Widget Interface, Next: Scrollbars, Up: Lucid Widget Library + +Generic Widget Interface +------------------------ + +In general in any toolkit a widget may be a composite object. In Xt, +all widgets have an X window that they manage, but typically a complex +widget will have widget children, each of which manages a subwindow of +the parent widget's X window. These children may themselves be +composite widgets. Thus a widget is actually a tree or hierarchy of +widgets. + + For each toolkit widget, lwlib maintains a tree of `widget_values' +which mirror the hierarchical state of Xt widgets (including Motif, +Athena, 3D Athena, and Falk's widget sets). Each `widget_value' has +`contents' member, which points to the head of a linked list of its +children. The linked list of siblings is chained through the `next' +member of `widget_value'. + + +-----------+ + | composite | + +-----------+ + | + | contents + V + +-------+ next +-------+ next +-------+ + | child |----->| child |----->| child | + +-------+ +-------+ +-------+ + | + | contents + V + +-------------+ next +-------------+ + | grand child |----->| grand child | + +-------------+ +-------------+ + + The `widget_value' hierarchy of a composite widget with two simple + children and one composite child. + + The `widget_instance' structure maintains the inverse view of the +tree. As for the `widget_value', siblings are chained through the +`next' member. However, rather than naming children, the +`widget_instance' tree links to parents. + + +-----------+ + | composite | + +-----------+ + A + | parent + | + +-------+ next +-------+ next +-------+ + | child |----->| child |----->| child | + +-------+ +-------+ +-------+ + A + | parent + | + +-------------+ next +-------------+ + | grand child |----->| grand child | + +-------------+ +-------------+ + + The `widget_value' hierarchy of a composite widget with two simple + children and one composite child. + + This permits widgets derived from different toolkits to be updated +and manipulated generically by the lwlib library. For instance +`update_one_widget_instance' can cope with multiple types of widget and +multiple types of toolkit. Each element in the widget hierarchy is +updated from its corresponding `widget_value' by walking the +`widget_value' tree. This has desirable properties. For example, +`lw_modify_all_widgets' is called from `glyphs-x.c' and updates all the +properties of a widget without having to know what the widget is or +what toolkit it is from. Unfortunately this also has its hairy +properties; the lwlib code quite complex. And of course lwlib has to +know at some level what the widget is and how to set its properties. + + The `widget_instance' structure also contains a pointer to the root +of its tree. Widget instances are further confi + + +File: internals.info, Node: Scrollbars, Next: Menubars, Prev: Generic Widget Interface, Up: Lucid Widget Library + +Scrollbars +---------- + + +File: internals.info, Node: Menubars, Next: Checkboxes and Radio Buttons, Prev: Scrollbars, Up: Lucid Widget Library + +Menubars +-------- + + +File: internals.info, Node: Checkboxes and Radio Buttons, Next: Progress Bars, Prev: Menubars, Up: Lucid Widget Library + +Checkboxes and Radio Buttons +---------------------------- + + +File: internals.info, Node: Progress Bars, Next: Tab Controls, Prev: Checkboxes and Radio Buttons, Up: Lucid Widget Library + +Progress Bars +------------- + + +File: internals.info, Node: Tab Controls, Prev: Progress Bars, Up: Lucid Widget Library + +Tab Controls +------------ + + +File: internals.info, Node: Index, Prev: Interface to the X Window System, Up: Top + +Index +***** + +* Menu: + +* allocation from frob blocks: Allocation from Frob Blocks. +* allocation of objects in XEmacs Lisp: Allocation of Objects in XEmacs Lisp. +* allocation, introduction to: Introduction to Allocation. +* allocation, low-level: Low-level allocation. +* Amdahl Corporation: XEmacs. +* Andreessen, Marc: XEmacs. +* asynchronous subprocesses: Modules for Interfacing with the Operating System. +* bars, progress: Progress Bars. +* Baur, Steve: XEmacs. +* Benson, Eric: Lucid Emacs. +* binding; the specbinding stack; unwind-protects, dynamic: Dynamic Binding; The specbinding Stack; Unwind-Protects. +* bindings, evaluation; stack frames;: Evaluation; Stack Frames; Bindings. +* bit vector: Bit Vector. +* bridge, playing: XEmacs From the Outside. +* Buchholz, Martin: XEmacs. +* Bufbyte: Character-Related Data Types. +* Bufbytes and Emchars: Bufbytes and Emchars. +* buffer lists: Buffer Lists. +* buffer object, the: The Buffer Object. +* buffer, the text in a: The Text in a Buffer. +* buffers and textual representation: Buffers and Textual Representation. +* buffers, introduction to: Introduction to Buffers. +* Bufpos: Character-Related Data Types. +* building, XEmacs from the perspective of: XEmacs From the Perspective of Building. +* buttons, checkboxes and radio: Checkboxes and Radio Buttons. +* byte positions, working with character and: Working With Character and Byte Positions. +* Bytecount: Character-Related Data Types. +* bytecount_to_charcount: Working With Character and Byte Positions. +* Bytind: Character-Related Data Types. +* C code, rules when writing new: Rules When Writing New C Code. +* C vs. Lisp: The Lisp Language. +* callback routines, the event stream: The Event Stream Callback Routines. +* caller-protects (GCPRO rule): Writing Lisp Primitives. +* case table: Modules for Other Aspects of the Lisp Interpreter and Object System. +* catch and throw: Catch and Throw. +* CCL: CCL. +* character and byte positions, working with: Working With Character and Byte Positions. +* character encoding, internal: Internal Character Encoding. +* character sets: Character Sets. +* character sets and encodings, Mule: MULE Character Sets and Encodings. +* character-related data types: Character-Related Data Types. +* characters, integers and: Integers and Characters. +* Charcount: Character-Related Data Types. +* charcount_to_bytecount: Working With Character and Byte Positions. +* charptr_emchar: Working With Character and Byte Positions. +* charptr_n_addr: Working With Character and Byte Positions. +* checkboxes and radio buttons: Checkboxes and Radio Buttons. +* closer: Lstream Methods. +* closure: The XEmacs Object System (Abstractly Speaking). +* code, an example of Mule-aware: An Example of Mule-Aware Code. +* code, general guidelines for writing Mule-aware: General Guidelines for Writing Mule-Aware Code. +* code, rules when writing new C: Rules When Writing New C Code. +* coding conventions: A Reader's Guide to XEmacs Coding Conventions. +* coding for Mule: Coding for Mule. +* coding rules, general: General Coding Rules. +* coding rules, naming: A Reader's Guide to XEmacs Coding Conventions. +* command builder, dispatching events; the: Dispatching Events; The Command Builder. +* comments, writing good: Writing Good Comments. +* Common Lisp: The Lisp Language. +* compact_string_chars: compact_string_chars. +* compiled function: Compiled Function. +* compiler, the Lisp reader and: The Lisp Reader and Compiler. +* cons: Cons. +* conservative garbage collection: GCPROing. +* consoles; devices; frames; windows: Consoles; Devices; Frames; Windows. +* consoles; devices; frames; windows, introduction to: Introduction to Consoles; Devices; Frames; Windows. +* control flow modules, editor-level: Editor-Level Control Flow Modules. +* conversion to and from external data: Conversion to and from External Data. +* converting events: Converting Events. +* copy-on-write: General Coding Rules. +* creating Lisp object types: Techniques for XEmacs Developers. +* critical redisplay sections: Critical Redisplay Sections. +* data dumping: Data dumping. +* data types, character-related: Character-Related Data Types. +* DEC_CHARPTR: Working With Character and Byte Positions. +* developers, techniques for XEmacs: Techniques for XEmacs Developers. +* devices; frames; windows, consoles;: Consoles; Devices; Frames; Windows. +* devices; frames; windows, introduction to consoles;: Introduction to Consoles; Devices; Frames; Windows. +* Devin, Matthieu: Lucid Emacs. +* dispatching events; the command builder: Dispatching Events; The Command Builder. +* display order of extents: Mathematics of Extent Ordering. +* display-related Lisp objects, modules for other: Modules for other Display-Related Lisp Objects. +* displayable Lisp objects, modules for the basic: Modules for the Basic Displayable Lisp Objects. +* dumping: Dumping. +* dumping address allocation: Address allocation. +* dumping and its justification, what is: Dumping. +* dumping data descriptions: Data descriptions. +* dumping object inventory: Object inventory. +* dumping overview: Overview. +* dumping phase: Dumping phase. +* dumping, data: Data dumping. +* dumping, file loading: Reloading phase. +* dumping, object relocation: Reloading phase. +* dumping, pointers: Pointers dumping. +* dumping, putting back the pdump_opaques: Reloading phase. +* dumping, putting back the pdump_root_objects and pdump_weak_object_chains: Reloading phase. +* dumping, putting back the pdump_root_struct_ptrs: Reloading phase. +* dumping, reloading phase: Reloading phase. +* dumping, remaining issues: Remaining issues. +* dumping, reorganize the hash tables: Reloading phase. +* dumping, the header: The header. +* dynamic array: Low-Level Modules. +* dynamic binding; the specbinding stack; unwind-protects: Dynamic Binding; The specbinding Stack; Unwind-Protects. +* dynamic scoping: The Lisp Language. +* dynamic types: The Lisp Language. +* editing operations, modules for standard: Modules for Standard Editing Operations. +* Emacs 19, GNU: GNU Emacs 19. +* Emacs 20, GNU: GNU Emacs 20. +* Emacs, a history of: A History of Emacs. +* Emchar: Character-Related Data Types. +* Emchars, Bufbytes and: Bufbytes and Emchars. +* encoding, internal character: Internal Character Encoding. +* encoding, internal string: Internal String Encoding. +* encodings, internal Mule: Internal Mule Encodings. +* encodings, Mule: Encodings. +* encodings, Mule character sets and: MULE Character Sets and Encodings. +* Energize: Lucid Emacs. +* Epoch <1>: XEmacs. +* Epoch: Lucid Emacs. +* error checking: Techniques for XEmacs Developers. +* EUC (Extended Unix Code), Japanese: Japanese EUC (Extended Unix Code). +* evaluation: Evaluation. +* evaluation; stack frames; bindings: Evaluation; Stack Frames; Bindings. +* event gathering mechanism, specifics of the: Specifics of the Event Gathering Mechanism. +* event loop functions, other: Other Event Loop Functions. +* event loop, events and the: Events and the Event Loop. +* event stream callback routines, the: The Event Stream Callback Routines. +* event, specifics about the Lisp object: Specifics About the Emacs Event. +* events and the event loop: Events and the Event Loop. +* events, converting: Converting Events. +* events, introduction to: Introduction to Events. +* events, main loop: Main Loop. +* events; the command builder, dispatching: Dispatching Events; The Command Builder. +* Extbyte: Character-Related Data Types. +* Extcount: Character-Related Data Types. +* Extended Unix Code, Japanese EUC: Japanese EUC (Extended Unix Code). +* extent fragments: Extent Fragments. +* extent info, format of the: Format of the Extent Info. +* extent mathematics: Mathematics of Extent Ordering. +* extent ordering <1>: Mathematics of Extent Ordering. +* extent ordering: Extent Ordering. +* extents: Extents. +* extents, display order: Mathematics of Extent Ordering. +* extents, introduction to: Introduction to Extents. +* extents, markers and: Markers and Extents. +* extents, zero-length: Zero-Length Extents. +* external data, conversion to and from: Conversion to and from External Data. +* external widget: Modules for Interfacing with X Windows. +* faces: Faces. +* file system, modules for interfacing with the: Modules for Interfacing with the File System. +* flusher: Lstream Methods. +* fragments, extent: Extent Fragments. +* frames; windows, consoles; devices;: Consoles; Devices; Frames; Windows. +* frames; windows, introduction to consoles; devices;: Introduction to Consoles; Devices; Frames; Windows. +* Free Software Foundation: A History of Emacs. +* frob blocks, allocation from: Allocation from Frob Blocks. +* FSF: A History of Emacs. +* FSF Emacs <1>: GNU Emacs 20. +* FSF Emacs: GNU Emacs 19. +* function, compiled: Compiled Function. +* garbage collection: Garbage Collection. +* garbage collection - step by step: Garbage Collection - Step by Step. +* garbage collection protection <1>: GCPROing. +* garbage collection protection: Writing Lisp Primitives. +* garbage collection, conservative: GCPROing. +* garbage collection, invocation: Invocation. +* garbage_collect_1: garbage_collect_1. +* gc_sweep: gc_sweep. +* GCPROing: GCPROing. +* global Lisp variables, adding: Adding Global Lisp Variables. +* glyph instantiation: Glyphs. +* glyphs: Glyphs. +* GNU Emacs 19: GNU Emacs 19. +* GNU Emacs 20: GNU Emacs 20. +* Gosling, James <1>: The Lisp Language. +* Gosling, James: Through Version 18. +* Great Usenet Renaming: Through Version 18. +* Hackers (Steven Levy): A History of Emacs. +* header files, inline functions: Techniques for XEmacs Developers. +* hierarchy of windows: Window Hierarchy. +* history of Emacs, a: A History of Emacs. +* Illinois, University of: XEmacs. +* INC_CHARPTR: Working With Character and Byte Positions. +* inline functions: Techniques for XEmacs Developers. +* inline functions, headers: Techniques for XEmacs Developers. +* inside, XEmacs from the: XEmacs From the Inside. +* instantiation, glyph: Glyphs. +* integers and characters: Integers and Characters. +* interactive: Modules for Standard Editing Operations. +* interfacing with the file system, modules for: Modules for Interfacing with the File System. +* interfacing with the operating system, modules for: Modules for Interfacing with the Operating System. +* interfacing with X Windows, modules for: Modules for Interfacing with X Windows. +* internal character encoding: Internal Character Encoding. +* internal Mule encodings: Internal Mule Encodings. +* internal string encoding: Internal String Encoding. +* internationalization, modules for: Modules for Internationalization. +* interning: The XEmacs Object System (Abstractly Speaking). +* interpreter and object system, modules for other aspects of the Lisp: Modules for Other Aspects of the Lisp Interpreter and Object System. +* ITS (Incompatible Timesharing System): A History of Emacs. +* Japanese EUC (Extended Unix Code): Japanese EUC (Extended Unix Code). +* Java: The Lisp Language. +* Java vs. Lisp: The Lisp Language. +* JIS7: JIS7. +* Jones, Kyle: XEmacs. +* Kaplan, Simon: XEmacs. +* Levy, Steven: A History of Emacs. +* library, Lucid Widget: Lucid Widget Library. +* line start cache: Line Start Cache. +* Lisp interpreter and object system, modules for other aspects of the: Modules for Other Aspects of the Lisp Interpreter and Object System. +* Lisp language, the: The Lisp Language. +* Lisp modules, basic: Basic Lisp Modules. +* Lisp object types, creating: Techniques for XEmacs Developers. +* Lisp objects are represented in C, how: How Lisp Objects Are Represented in C. +* Lisp objects, allocation of in XEmacs: Allocation of Objects in XEmacs Lisp. +* Lisp objects, modules for other display-related: Modules for other Display-Related Lisp Objects. +* Lisp objects, modules for the basic displayable: Modules for the Basic Displayable Lisp Objects. +* Lisp primitives, writing: Writing Lisp Primitives. +* Lisp reader and compiler, the: The Lisp Reader and Compiler. +* Lisp vs. C: The Lisp Language. +* Lisp vs. Java: The Lisp Language. +* low-level allocation: Low-level allocation. +* low-level modules: Low-Level Modules. +* lrecords: lrecords. +* lstream: Modules for Interfacing with the File System. +* lstream functions: Lstream Functions. +* lstream methods: Lstream Methods. +* lstream types: Lstream Types. +* lstream, creating an: Creating an Lstream. +* Lstream_close: Lstream Functions. +* Lstream_fgetc: Lstream Functions. +* Lstream_flush: Lstream Functions. +* Lstream_fputc: Lstream Functions. +* Lstream_fungetc: Lstream Functions. +* Lstream_getc: Lstream Functions. +* Lstream_new: Lstream Functions. +* Lstream_putc: Lstream Functions. +* Lstream_read: Lstream Functions. +* Lstream_reopen: Lstream Functions. +* Lstream_rewind: Lstream Functions. +* Lstream_set_buffering: Lstream Functions. +* Lstream_ungetc: Lstream Functions. +* Lstream_unread: Lstream Functions. +* Lstream_write: Lstream Functions. +* lstreams: Lstreams. +* Lucid Emacs: Lucid Emacs. +* Lucid Inc.: Lucid Emacs. +* Lucid Widget Library: Lucid Widget Library. +* macro hygiene: Techniques for XEmacs Developers. +* main loop: Main Loop. +* mark and sweep: Garbage Collection. +* mark method <1>: lrecords. +* mark method: Modules for Other Aspects of the Lisp Interpreter and Object System. +* mark_object: mark_object. +* marker <1>: Lstream Methods. +* marker: Marker. +* markers and extents: Markers and Extents. +* mathematics of extent ordering: Mathematics of Extent Ordering. +* MAX_EMCHAR_LEN: Working With Character and Byte Positions. +* menubars: Menubars. +* menus: Menus. +* merging attempts: XEmacs. +* MIT: A History of Emacs. +* Mlynarik, Richard: GNU Emacs 19. +* modules for interfacing with the file system: Modules for Interfacing with the File System. +* modules for interfacing with the operating system: Modules for Interfacing with the Operating System. +* modules for interfacing with X Windows: Modules for Interfacing with X Windows. +* modules for internationalization: Modules for Internationalization. +* modules for other aspects of the Lisp interpreter and object system: Modules for Other Aspects of the Lisp Interpreter and Object System. +* modules for other display-related Lisp objects: Modules for other Display-Related Lisp Objects. +* modules for regression testing: Modules for Regression Testing. +* modules for standard editing operations: Modules for Standard Editing Operations. +* modules for the basic displayable Lisp objects: Modules for the Basic Displayable Lisp Objects. +* modules for the redisplay mechanism: Modules for the Redisplay Mechanism. +* modules, a summary of the various XEmacs: A Summary of the Various XEmacs Modules. +* modules, basic Lisp: Basic Lisp Modules. +* modules, editor-level control flow: Editor-Level Control Flow Modules. +* modules, low-level: Low-Level Modules. +* MS-Windows environment, widget-glyphs in the: Glyphs. +* Mule character sets and encodings: MULE Character Sets and Encodings. +* Mule encodings: Encodings. +* Mule encodings, internal: Internal Mule Encodings. +* MULE merged XEmacs appears: XEmacs. +* Mule, coding for: Coding for Mule. +* Mule-aware code, an example of: An Example of Mule-Aware Code. +* Mule-aware code, general guidelines for writing: General Guidelines for Writing Mule-Aware Code. +* NAS: Modules for Interfacing with the Operating System. +* native sound: Modules for Interfacing with the Operating System. +* network connections: Modules for Interfacing with the Operating System. +* network sound: Modules for Interfacing with the Operating System. +* Niksic, Hrvoje: XEmacs. +* obarrays: Obarrays. +* object system (abstractly speaking), the XEmacs: The XEmacs Object System (Abstractly Speaking). +* object system, modules for other aspects of the Lisp interpreter and: Modules for Other Aspects of the Lisp Interpreter and Object System. +* object types, creating Lisp: Techniques for XEmacs Developers. +* object, the buffer: The Buffer Object. +* object, the window: The Window Object. +* objects are represented in C, how Lisp: How Lisp Objects Are Represented in C. +* objects in XEmacs Lisp, allocation of: Allocation of Objects in XEmacs Lisp. +* objects, modules for the basic displayable Lisp: Modules for the Basic Displayable Lisp Objects. +* operating system, modules for interfacing with the: Modules for Interfacing with the Operating System. +* outside, XEmacs from the: XEmacs From the Outside. +* pane: Modules for the Basic Displayable Lisp Objects. +* permanent objects: The XEmacs Object System (Abstractly Speaking). +* pi, calculating: XEmacs From the Outside. +* point: Point. +* pointers dumping: Pointers dumping. +* positions, working with character and byte: Working With Character and Byte Positions. +* primitives, writing Lisp: Writing Lisp Primitives. +* progress bars: Progress Bars. +* protection, garbage collection: GCPROing. +* pseudo_closer: Lstream Methods. +* Purify: Techniques for XEmacs Developers. +* Quantify: Techniques for XEmacs Developers. +* radio buttons, checkboxes and: Checkboxes and Radio Buttons. +* read syntax: The XEmacs Object System (Abstractly Speaking). +* read-eval-print: XEmacs From the Outside. +* reader: Lstream Methods. +* reader and compiler, the Lisp: The Lisp Reader and Compiler. +* reader's guide: A Reader's Guide to XEmacs Coding Conventions. +* redisplay mechanism, modules for the: Modules for the Redisplay Mechanism. +* redisplay mechanism, the: The Redisplay Mechanism. +* redisplay piece by piece: Redisplay Piece by Piece. +* redisplay sections, critical: Critical Redisplay Sections. +* regression testing, modules for: Modules for Regression Testing. +* reloading phase: Reloading phase. +* relocating allocator: Low-Level Modules. +* rename to XEmacs: XEmacs. +* represented in C, how Lisp objects are: How Lisp Objects Are Represented in C. +* rewinder: Lstream Methods. +* RMS: A History of Emacs. +* scanner: Modules for Other Aspects of the Lisp Interpreter and Object System. +* scoping, dynamic: The Lisp Language. +* scrollbars: Scrollbars. +* seekable_p: Lstream Methods. +* selections: Modules for Interfacing with X Windows. +* set_charptr_emchar: Working With Character and Byte Positions. +* Sexton, Harlan: Lucid Emacs. +* sound, native: Modules for Interfacing with the Operating System. +* sound, network: Modules for Interfacing with the Operating System. +* SPARCWorks: XEmacs. +* specbinding stack; unwind-protects, dynamic binding; the: Dynamic Binding; The specbinding Stack; Unwind-Protects. +* special forms, simple: Simple Special Forms. +* specifiers: Specifiers. +* stack frames; bindings, evaluation;: Evaluation; Stack Frames; Bindings. +* Stallman, Richard: A History of Emacs. +* string: String. +* string encoding, internal: Internal String Encoding. +* subprocesses: Subprocesses. +* subprocesses, asynchronous: Modules for Interfacing with the Operating System. +* subprocesses, synchronous: Modules for Interfacing with the Operating System. +* Sun Microsystems: XEmacs. +* sweep_bit_vectors_1: sweep_bit_vectors_1. +* sweep_lcrecords_1: sweep_lcrecords_1. +* sweep_strings: sweep_strings. +* symbol: Symbol. +* symbol values: Symbol Values. +* symbols and variables: Symbols and Variables. +* symbols, introduction to: Introduction to Symbols. +* synchronous subprocesses: Modules for Interfacing with the Operating System. +* tab controls: Tab Controls. +* taxes, doing: XEmacs From the Outside. +* techniques for XEmacs developers: Techniques for XEmacs Developers. +* TECO: A History of Emacs. +* temporary objects: The XEmacs Object System (Abstractly Speaking). +* testing, regression: Regression Testing XEmacs. +* text in a buffer, the: The Text in a Buffer. +* textual representation, buffers and: Buffers and Textual Representation. +* Thompson, Chuck: XEmacs. +* throw, catch and: Catch and Throw. +* types, dynamic: The Lisp Language. +* types, lstream: Lstream Types. +* types, proper use of unsigned: Proper Use of Unsigned Types. +* University of Illinois: XEmacs. +* unsigned types, proper use of: Proper Use of Unsigned Types. +* unwind-protects, dynamic binding; the specbinding stack;: Dynamic Binding; The specbinding Stack; Unwind-Protects. +* values, symbol: Symbol Values. +* variables, adding global Lisp: Adding Global Lisp Variables. +* variables, symbols and: Symbols and Variables. +* vector: Vector. +* vector, bit: Bit Vector. +* version 18, through: Through Version 18. +* version 19, GNU Emacs: GNU Emacs 19. +* version 20, GNU Emacs: GNU Emacs 20. +* widget interface, generic: Generic Widget Interface. +* widget library, Lucid: Lucid Widget Library. +* widget-glyphs: Glyphs. +* widget-glyphs in the MS-Windows environment: Glyphs. +* widget-glyphs in the X environment: Glyphs. +* Win-Emacs: XEmacs. +* window (in Emacs): Modules for the Basic Displayable Lisp Objects. +* window hierarchy: Window Hierarchy. +* window object, the: The Window Object. +* window point internals: The Window Object. +* windows, consoles; devices; frames;: Consoles; Devices; Frames; Windows. +* windows, introduction to consoles; devices; frames;: Introduction to Consoles; Devices; Frames; Windows. +* Wing, Ben: XEmacs. +* writer: Lstream Methods. +* writing good comments: Writing Good Comments. +* writing Lisp primitives: Writing Lisp Primitives. +* writing Mule-aware code, general guidelines for: General Guidelines for Writing Mule-Aware Code. +* writing new C code, rules when: Rules When Writing New C Code. +* X environment, widget-glyphs in the: Glyphs. +* X Window System, interface to the: Interface to the X Window System. +* X Windows, modules for interfacing with: Modules for Interfacing with X Windows. +* XEmacs: XEmacs. +* XEmacs from the inside: XEmacs From the Inside. +* XEmacs from the outside: XEmacs From the Outside. +* XEmacs from the perspective of building: XEmacs From the Perspective of Building. +* XEmacs goes it alone: XEmacs. +* XEmacs object system (abstractly speaking), the: The XEmacs Object System (Abstractly Speaking). +* Zawinski, Jamie: Lucid Emacs. +* zero-length extents: Zero-Length Extents. + diff -u -r -N xemacs-21.4.14/info/internals.info-3 xemacs-21.4.15/info/internals.info-3 --- xemacs-21.4.14/info/internals.info-3 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-3 1969-12-31 19:00:00.000000000 -0500 @@ -1,1106 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Character-Related Data Types, Next: Working With Character and Byte Positions, Up: Coding for Mule - -Character-Related Data Types ----------------------------- - - First, let's review the basic character-related datatypes used by -XEmacs. Note that the separate `typedef's are not mandatory in the -current implementation (all of them boil down to `unsigned char' or -`int'), but they improve clarity of code a great deal, because one -glance at the declaration can tell the intended use of the variable. - -`Emchar' - An `Emchar' holds a single Emacs character. - - Obviously, the equality between characters and bytes is lost in - the Mule world. Characters can be represented by one or more - bytes in the buffer, and `Emchar' is the C type large enough to - hold any character. - - Without Mule support, an `Emchar' is equivalent to an `unsigned - char'. - -`Bufbyte' - The data representing the text in a buffer or string is logically - a set of `Bufbyte's. - - XEmacs does not work with the same character formats all the time; - when reading characters from the outside, it decodes them to an - internal format, and likewise encodes them when writing. - `Bufbyte' (in fact `unsigned char') is the basic unit of XEmacs - internal buffers and strings format. A `Bufbyte *' is the type - that points at text encoded in the variable-width internal - encoding. - - One character can correspond to one or more `Bufbyte's. In the - current Mule implementation, an ASCII character is represented by - the same `Bufbyte', and other characters are represented by a - sequence of two or more `Bufbyte's. - - Without Mule support, there are exactly 256 characters, implicitly - Latin-1, and each character is represented using one `Bufbyte', and - there is a one-to-one correspondence between `Bufbyte's and - `Emchar's. - -`Bufpos' -`Charcount' - A `Bufpos' represents a character position in a buffer or string. - A `Charcount' represents a number (count) of characters. - Logically, subtracting two `Bufpos' values yields a `Charcount' - value. Although all of these are `typedef'ed to `EMACS_INT', we - use them in preference to `EMACS_INT' to make it clear what sort - of position is being used. - - `Bufpos' and `Charcount' values are the only ones that are ever - visible to Lisp. - -`Bytind' -`Bytecount' - A `Bytind' represents a byte position in a buffer or string. A - `Bytecount' represents the distance between two positions, in - bytes. The relationship between `Bytind' and `Bytecount' is the - same as the relationship between `Bufpos' and `Charcount'. - -`Extbyte' -`Extcount' - When dealing with the outside world, XEmacs works with `Extbyte's, - which are equivalent to `unsigned char'. Obviously, an `Extcount' - is the distance between two `Extbyte's. Extbytes and Extcounts - are not all that frequent in XEmacs code. - - -File: internals.info, Node: Working With Character and Byte Positions, Next: Conversion to and from External Data, Prev: Character-Related Data Types, Up: Coding for Mule - -Working With Character and Byte Positions ------------------------------------------ - - Now that we have defined the basic character-related types, we can -look at the macros and functions designed for work with them and for -conversion between them. Most of these macros are defined in -`buffer.h', and we don't discuss all of them here, but only the most -important ones. Examining the existing code is the best way to learn -about them. - -`MAX_EMCHAR_LEN' - This preprocessor constant is the maximum number of buffer bytes to - represent an Emacs character in the variable width internal - encoding. It is useful when allocating temporary strings to keep - a known number of characters. For instance: - - { - Charcount cclen; - ... - { - /* Allocate place for CCLEN characters. */ - Bufbyte *buf = (Bufbyte *)alloca (cclen * MAX_EMCHAR_LEN); - ... - - If you followed the previous section, you can guess that, - logically, multiplying a `Charcount' value with `MAX_EMCHAR_LEN' - produces a `Bytecount' value. - - In the current Mule implementation, `MAX_EMCHAR_LEN' equals 4. - Without Mule, it is 1. - -`charptr_emchar' -`set_charptr_emchar' - The `charptr_emchar' macro takes a `Bufbyte' pointer and returns - the `Emchar' stored at that position. If it were a function, its - prototype would be: - - Emchar charptr_emchar (Bufbyte *p); - - `set_charptr_emchar' stores an `Emchar' to the specified byte - position. It returns the number of bytes stored: - - Bytecount set_charptr_emchar (Bufbyte *p, Emchar c); - - It is important to note that `set_charptr_emchar' is safe only for - appending a character at the end of a buffer, not for overwriting a - character in the middle. This is because the width of characters - varies, and `set_charptr_emchar' cannot resize the string if it - writes, say, a two-byte character where a single-byte character - used to reside. - - A typical use of `set_charptr_emchar' can be demonstrated by this - example, which copies characters from buffer BUF to a temporary - string of Bufbytes. - - { - Bufpos pos; - for (pos = beg; pos < end; pos++) - { - Emchar c = BUF_FETCH_CHAR (buf, pos); - p += set_charptr_emchar (buf, c); - } - } - - Note how `set_charptr_emchar' is used to store the `Emchar' and - increment the counter, at the same time. - -`INC_CHARPTR' -`DEC_CHARPTR' - These two macros increment and decrement a `Bufbyte' pointer, - respectively. They will adjust the pointer by the appropriate - number of bytes according to the byte length of the character - stored there. Both macros assume that the memory address is - located at the beginning of a valid character. - - Without Mule support, `INC_CHARPTR (p)' and `DEC_CHARPTR (p)' - simply expand to `p++' and `p--', respectively. - -`bytecount_to_charcount' - Given a pointer to a text string and a length in bytes, return the - equivalent length in characters. - - Charcount bytecount_to_charcount (Bufbyte *p, Bytecount bc); - -`charcount_to_bytecount' - Given a pointer to a text string and a length in characters, - return the equivalent length in bytes. - - Bytecount charcount_to_bytecount (Bufbyte *p, Charcount cc); - -`charptr_n_addr' - Return a pointer to the beginning of the character offset CC (in - characters) from P. - - Bufbyte *charptr_n_addr (Bufbyte *p, Charcount cc); - - -File: internals.info, Node: Conversion to and from External Data, Next: General Guidelines for Writing Mule-Aware Code, Prev: Working With Character and Byte Positions, Up: Coding for Mule - -Conversion to and from External Data ------------------------------------- - - When an external function, such as a C library function, returns a -`char' pointer, you should almost never treat it as `Bufbyte'. This is -because these returned strings may contain 8bit characters which can be -misinterpreted by XEmacs, and cause a crash. Likewise, when exporting -a piece of internal text to the outside world, you should always -convert it to an appropriate external encoding, lest the internal stuff -(such as the infamous \201 characters) leak out. - - The interface to conversion between the internal and external -representations of text are the numerous conversion macros defined in -`buffer.h'. There used to be a fixed set of external formats supported -by these macros, but now any coding system can be used with these -macros. The coding system alias mechanism is used to create the -following logical coding systems, which replace the fixed external -formats. The (dontusethis-set-symbol-value-handler) mechanism was -enhanced to make this possible (more work on that is needed - like -remove the `dontusethis-' prefix). - -`Qbinary' - This is the simplest format and is what we use in the absence of a - more appropriate format. This converts according to the `binary' - coding system: - - a. On input, bytes 0-255 are converted into (implicitly Latin-1) - characters 0-255. A non-Mule xemacs doesn't really know about - different character sets and the fonts to display them, so - the bytes can be treated as text in different 1-byte - encodings by simply setting the appropriate fonts. So in a - sense, non-Mule xemacs is a multi-lingual editor if, for - example, different fonts are used to display text in - different buffers, faces, or windows. The specifier - mechanism gives the user complete control over this kind of - behavior. - - b. On output, characters 0-255 are converted into bytes 0-255 - and other characters are converted into `~'. - -`Qfile_name' - Format used for filenames. This is user-definable via either the - `file-name-coding-system' or `pathname-coding-system' (now - obsolete) variables. - -`Qnative' - Format used for the external Unix environment--`argv[]', stuff - from `getenv()', stuff from the `/etc/passwd' file, etc. - Currently this is the same as Qfile_name. The two should be - distinguished for clarity and possible future separation. - -`Qctext' - Compound-text format. This is the standard X11 format used for - data stored in properties, selections, and the like. This is an - 8-bit no-lock-shift ISO2022 coding system. This is a real coding - system, unlike Qfile_name, which is user-definable. - - There are two fundamental macros to convert between external and -internal format. - - `TO_INTERNAL_FORMAT' converts external data to internal format, and -`TO_EXTERNAL_FORMAT' converts the other way around. The arguments each -of these receives are a source type, a source, a sink type, a sink, and -a coding system (or a symbol naming a coding system). - - A typical call looks like - TO_EXTERNAL_FORMAT (LISP_STRING, str, C_STRING_MALLOC, ptr, Qfile_name); - - which means that the contents of the lisp string `str' are written -to a malloc'ed memory area which will be pointed to by `ptr', after the -function returns. The conversion will be done using the `file-name' -coding system, which will be controlled by the user indirectly by -setting or binding the variable `file-name-coding-system'. - - Some sources and sinks require two C variables to specify. We use -some preprocessor magic to allow different source and sink types, and -even different numbers of arguments to specify different types of -sources and sinks. - - So we can have a call that looks like - TO_INTERNAL_FORMAT (DATA, (ptr, len), - MALLOC, (ptr, len), - coding_system); - - The parenthesized argument pairs are required to make the -preprocessor magic work. - - Here are the different source and sink types: - -``DATA, (ptr, len),'' - input data is a fixed buffer of size LEN at address PTR - -``ALLOCA, (ptr, len),'' - output data is placed in an alloca()ed buffer of size LEN pointed - to by PTR - -``MALLOC, (ptr, len),'' - output data is in a malloc()ed buffer of size LEN pointed to by PTR - -``C_STRING_ALLOCA, ptr,'' - equivalent to `ALLOCA (ptr, len_ignored)' on output. - -``C_STRING_MALLOC, ptr,'' - equivalent to `MALLOC (ptr, len_ignored)' on output - -``C_STRING, ptr,'' - equivalent to `DATA, (ptr, strlen (ptr) + 1)' on input - -``LISP_STRING, string,'' - input or output is a Lisp_Object of type string - -``LISP_BUFFER, buffer,'' - output is written to `(point)' in lisp buffer BUFFER - -``LISP_LSTREAM, lstream,'' - input or output is a Lisp_Object of type lstream - -``LISP_OPAQUE, object,'' - input or output is a Lisp_Object of type opaque - - Often, the data is being converted to a '\0'-byte-terminated string, -which is the format required by many external system C APIs. For these -purposes, a source type of `C_STRING' or a sink type of -`C_STRING_ALLOCA' or `C_STRING_MALLOC' is appropriate. Otherwise, we -should try to keep XEmacs '\0'-byte-clean, which means using (ptr, len) -pairs. - - The sinks to be specified must be lvalues, unless they are the lisp -object types `LISP_LSTREAM' or `LISP_BUFFER'. - - For the sink types `ALLOCA' and `C_STRING_ALLOCA', the resulting -text is stored in a stack-allocated buffer, which is automatically -freed on returning from the function. However, the sink types `MALLOC' -and `C_STRING_MALLOC' return `xmalloc()'ed memory. The caller is -responsible for freeing this memory using `xfree()'. - - Note that it doesn't make sense for `LISP_STRING' to be a source for -`TO_INTERNAL_FORMAT' or a sink for `TO_EXTERNAL_FORMAT'. You'll get an -assertion failure if you try. - - -File: internals.info, Node: General Guidelines for Writing Mule-Aware Code, Next: An Example of Mule-Aware Code, Prev: Conversion to and from External Data, Up: Coding for Mule - -General Guidelines for Writing Mule-Aware Code ----------------------------------------------- - - This section contains some general guidance on how to write -Mule-aware code, as well as some pitfalls you should avoid. - -_Never use `char' and `char *'._ - In XEmacs, the use of `char' and `char *' is almost always a - mistake. If you want to manipulate an Emacs character from "C", - use `Emchar'. If you want to examine a specific octet in the - internal format, use `Bufbyte'. If you want a Lisp-visible - character, use a `Lisp_Object' and `make_char'. If you want a - pointer to move through the internal text, use `Bufbyte *'. Also - note that you almost certainly do not need `Emchar *'. - -_Be careful not to confuse `Charcount', `Bytecount', and `Bufpos'._ - The whole point of using different types is to avoid confusion - about the use of certain variables. Lest this effect be - nullified, you need to be careful about using the right types. - -_Always convert external data_ - It is extremely important to always convert external data, because - XEmacs can crash if unexpected 8bit sequences are copied to its - internal buffers literally. - - This means that when a system function, such as `readdir', returns - a string, you may need to convert it using one of the conversion - macros described in the previous chapter, before passing it - further to Lisp. - - Actually, most of the basic system functions that accept - '\0'-terminated string arguments, like `stat()' and `open()', have - been *encapsulated* so that they are they `always' do internal to - external conversion themselves. This means you must pass - internally encoded data, typically the `XSTRING_DATA' of a - Lisp_String to these functions. This is actually a design bug, - since it unexpectedly changes the semantics of the system - functions. A better design would be to provide separate versions - of these system functions that accepted Lisp_Objects which were - lisp strings in place of their current `char *' arguments. - - int stat_lisp (Lisp_Object path, struct stat *buf); /* Implement me */ - - Also note that many internal functions, such as `make_string', - accept Bufbytes, which removes the need for them to convert the - data they receive. This increases efficiency because that way - external data needs to be decoded only once, when it is read. - After that, it is passed around in internal format. - - -File: internals.info, Node: An Example of Mule-Aware Code, Prev: General Guidelines for Writing Mule-Aware Code, Up: Coding for Mule - -An Example of Mule-Aware Code ------------------------------ - - As an example of Mule-aware code, we will analyze the `string' -function, which conses up a Lisp string from the character arguments it -receives. Here is the definition, pasted from `alloc.c': - - DEFUN ("string", Fstring, 0, MANY, 0, /* - Concatenate all the argument characters and make the result a string. - */ - (int nargs, Lisp_Object *args)) - { - Bufbyte *storage = alloca_array (Bufbyte, nargs * MAX_EMCHAR_LEN); - Bufbyte *p = storage; - - for (; nargs; nargs--, args++) - { - Lisp_Object lisp_char = *args; - CHECK_CHAR_COERCE_INT (lisp_char); - p += set_charptr_emchar (p, XCHAR (lisp_char)); - } - return make_string (storage, p - storage); - } - - Now we can analyze the source line by line. - - Obviously, string will be as long as there are arguments to the -function. This is why we allocate `MAX_EMCHAR_LEN' * NARGS bytes on -the stack, i.e. the worst-case number of bytes for NARGS `Emchar's to -fit in the string. - - Then, the loop checks that each element is a character, converting -integers in the process. Like many other functions in XEmacs, this -function silently accepts integers where characters are expected, for -historical and compatibility reasons. Unless you know what you are -doing, `CHECK_CHAR' will also suffice. `XCHAR (lisp_char)' extracts -the `Emchar' from the `Lisp_Object', and `set_charptr_emchar' stores it -to storage, increasing `p' in the process. - - Other instructive examples of correct coding under Mule can be found -all over the XEmacs code. For starters, I recommend -`Fnormalize_menu_item_name' in `menubar.c'. After you have understood -this section of the manual and studied the examples, you can proceed -writing new Mule-aware code. - - -File: internals.info, Node: Techniques for XEmacs Developers, Prev: Coding for Mule, Up: Rules When Writing New C Code - -Techniques for XEmacs Developers -================================ - - To make a purified XEmacs, do: `make puremacs'. To make a -quantified XEmacs, do: `make quantmacs'. - - You simply can't dump Quantified and Purified images (unless using -the portable dumper). Purify gets confused when xemacs frees memory in -one process that was allocated in a _different_ process on a different -machine!. Run it like so: - temacs -batch -l loadup.el run-temacs XEMACS-ARGS... - - Before you go through the trouble, are you compiling with all -debugging and error-checking off? If not, try that first. Be warned -that while Quantify is directly responsible for quite a few -optimizations which have been made to XEmacs, doing a run which -generates results which can be acted upon is not necessarily a trivial -task. - - Also, if you're still willing to do some runs make sure you configure -with the `--quantify' flag. That will keep Quantify from starting to -record data until after the loadup is completed and will shut off -recording right before it shuts down (which generates enough bogus data -to throw most results off). It also enables three additional elisp -commands: `quantify-start-recording-data', -`quantify-stop-recording-data' and `quantify-clear-data'. - - If you want to make XEmacs faster, target your favorite slow -benchmark, run a profiler like Quantify, `gprof', or `tcov', and figure -out where the cycles are going. In many cases you can localize the -problem (because a particular new feature or even a single patch -elicited it). Don't hesitate to use brute force techniques like a -global counter incremented at strategic places, especially in -combination with other performance indications (_e.g._, degree of -buffer fragmentation into extents). - - Specific projects: - - * Make the garbage collector faster. Figure out how to write an - incremental garbage collector. - - * Write a compiler that takes bytecode and spits out C code. - Unfortunately, you will then need a C compiler and a more fully - developed module system. - - * Speed up redisplay. - - * Speed up syntax highlighting. It was suggested that "maybe moving - some of the syntax highlighting capabilities into C would make a - difference." Wrong idea, I think. When processing one large file - a particular low-level routine was being called 40 _million_ times - simply for _one_ call to `newline-and-indent'. Syntax - highlighting needs to be rewritten to use a reliable, fast parser, - then to trust the pre-parsed structure, and only do - re-highlighting locally to a text change. Modern machines are - fast enough to implement such parsers in Lisp; but no machine will - ever be fast enough to deal with quadratic (or worse) algorithms! - - * Implement tail recursion in Emacs Lisp (hard!). - - Unfortunately, Emacs Lisp is slow, and is going to stay slow. -Function calls in elisp are especially expensive. Iterating over a -long list is going to be 30 times faster implemented in C than in Elisp. - - Heavily used small code fragments need to be fast. The traditional -way to implement such code fragments in C is with macros. But macros -in C are known to be broken. - - Macro arguments that are repeatedly evaluated may suffer from -repeated side effects or suboptimal performance. - - Variable names used in macros may collide with caller's variables, -causing (at least) unwanted compiler warnings. - - In order to solve these problems, and maintain statement semantics, -one should use the `do { ... } while (0)' trick while trying to -reference macro arguments exactly once using local variables. - - Let's take a look at this poor macro definition: - - #define MARK_OBJECT(obj) \ - if (!marked_p (obj)) mark_object (obj), did_mark = 1 - - This macro evaluates its argument twice, and also fails if used like -this: - if (flag) MARK_OBJECT (obj); else do_something(); - - A much better definition is - - #define MARK_OBJECT(obj) do { \ - Lisp_Object mo_obj = (obj); \ - if (!marked_p (mo_obj)) \ - { \ - mark_object (mo_obj); \ - did_mark = 1; \ - } \ - } while (0) - - Notice the elimination of double evaluation by using the local -variable with the obscure name. Writing safe and efficient macros -requires great care. The one problem with macros that cannot be -portably worked around is, since a C block has no value, a macro used -as an expression rather than a statement cannot use the techniques just -described to avoid multiple evaluation. - - In most cases where a macro has function semantics, an inline -function is a better implementation technique. Modern compiler -optimizers tend to inline functions even if they have no `inline' -keyword, and configure magic ensures that the `inline' keyword can be -safely used as an additional compiler hint. Inline functions used in a -single .c files are easy. The function must already be defined to be -`static'. Just add another `inline' keyword to the definition. - - inline static int - heavily_used_small_function (int arg) - { - ... - } - - Inline functions in header files are trickier, because we would like -to make the following optimization if the function is _not_ inlined -(for example, because we're compiling for debugging). We would like the -function to be defined externally exactly once, and each calling -translation unit would create an external reference to the function, -instead of including a definition of the inline function in the object -code of every translation unit that uses it. This optimization is -currently only available for gcc. But you don't have to worry about the -trickiness; just define your inline functions in header files using this -pattern: - - INLINE_HEADER int - i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg); - INLINE_HEADER int - i_used_to_be_a_crufty_macro_but_look_at_me_now (int arg) - { - ... - } - - The declaration right before the definition is to prevent warnings -when compiling with `gcc -Wmissing-declarations'. I consider issuing -this warning for inline functions a gcc bug, but the gcc maintainers -disagree. - - Every header which contains inline functions, either directly by -using `INLINE_HEADER' or indirectly by using `DECLARE_LRECORD' must be -added to `inline.c''s includes to make the optimization described above -work. (Optimization note: if all INLINE_HEADER functions are in fact -inlined in all translation units, then the linker can just discard -`inline.o', since it contains only unreferenced code). - - To get started debugging XEmacs, take a look at the `.gdbinit' and -`.dbxrc' files in the `src' directory. See the section in the XEmacs -FAQ on How to Debug an XEmacs problem with a debugger. - - After making source code changes, run `make check' to ensure that -you haven't introduced any regressions. If you want to make xemacs more -reliable, please improve the test suite in `tests/automated'. - - Did you make sure you didn't introduce any new compiler warnings? - - Before submitting a patch, please try compiling at least once with - - configure --with-mule --use-union-type --error-checking=all - - Here are things to know when you create a new source file: - - * All `.c' files should `#include ' first. Almost all - `.c' files should `#include "lisp.h"' second. - - * Generated header files should be included using the `#include - <...>' syntax, not the `#include "..."' syntax. The generated - headers are: - - `config.h sheap-adjust.h paths.h Emacs.ad.h' - - The basic rule is that you should assume builds using `--srcdir' - and the `#include <...>' syntax needs to be used when the - to-be-included generated file is in a potentially different - directory _at compile time_. The non-obvious C rule is that - `#include "..."' means to search for the included file in the same - directory as the including file, _not_ in the current directory. - - * Header files should _not_ include `' and `"lisp.h"'. It - is the responsibility of the `.c' files that use it to do so. - - - Here is a checklist of things to do when creating a new lisp object -type named FOO: - - 1. create FOO.h - - 2. create FOO.c - - 3. add definitions of `syms_of_FOO', etc. to `FOO.c' - - 4. add declarations of `syms_of_FOO', etc. to `symsinit.h' - - 5. add calls to `syms_of_FOO', etc. to `emacs.c' - - 6. add definitions of macros like `CHECK_FOO' and `FOOP' to `FOO.h' - - 7. add the new type index to `enum lrecord_type' - - 8. add a DEFINE_LRECORD_IMPLEMENTATION call to `FOO.c' - - 9. add an INIT_LRECORD_IMPLEMENTATION call to `syms_of_FOO.c' - - -File: internals.info, Node: Regression Testing XEmacs, Next: A Summary of the Various XEmacs Modules, Prev: Rules When Writing New C Code, Up: Top - -Regression Testing XEmacs -************************* - - The source directory `tests/automated' contains XEmacs' automated -test suite. The usual way of running all the tests is running `make -check' from the top-level source directory. - - The test suite is unfinished and it's still lacking some essential -features. It is nevertheless recommended that you run the tests to -confirm that XEmacs behaves correctly. - - If you want to run a specific test case, you can do it from the -command-line like this: - - $ xemacs -batch -l test-harness.elc -f batch-test-emacs TEST-FILE - - If something goes wrong, you can run the test suite interactively by -loading `test-harness.el' into a running XEmacs and typing `M-x -test-emacs-test-file RET RET'. You will see a log of passed -and failed tests, which should allow you to investigate the source of -the error and ultimately fix the bug. - - Adding a new test file is trivial: just create a new file here and it -will be run. There is no need to byte-compile any of the files in this -directory--the test-harness will take care of any necessary -byte-compilation. - - Look at the existing test cases for the examples of coding test -cases. It all boils down to your imagination and judicious use of the -macros `Assert', `Check-Error', `Check-Error-Message', and -`Check-Message'. - - Here's a simple example checking case-sensitive and case-insensitive -comparisons from `case-tests.el'. - - (with-temp-buffer - (insert "Test Buffer") - (let ((case-fold-search t)) - (goto-char (point-min)) - (Assert (eq (search-forward "test buffer" nil t) 12)) - (goto-char (point-min)) - (Assert (eq (search-forward "Test buffer" nil t) 12)) - (goto-char (point-min)) - (Assert (eq (search-forward "Test Buffer" nil t) 12)) - - (setq case-fold-search nil) - (goto-char (point-min)) - (Assert (not (search-forward "test buffer" nil t))) - (goto-char (point-min)) - (Assert (not (search-forward "Test buffer" nil t))) - (goto-char (point-min)) - (Assert (eq (search-forward "Test Buffer" nil t) 12)))) - - This example could be inserted in a file in `tests/automated', and -it would be a complete test, automatically executed when you run `make -check' after building XEmacs. More complex tests may require -substantial temporary scaffolding to create the environment that elicits -the bugs, but the top-level Makefile and `test-harness.el' handle the -running and collection of results from the `Assert', `Check-Error', -`Check-Error-Message', and `Check-Message' macros. - - In general, you should avoid using functionality from packages in -your tests, because you can't be sure that everyone will have the -required package. However, if you've got a test that works, by all -means add it. Simply wrap the test in an appropriate test, add a -notice that the test was skipped, and update the `skipped-test-reasons' -hashtable. Here's an example from `syntax-tests.el': - - ;; Test forward-comment at buffer boundaries - (with-temp-buffer - - ;; try to use exactly what you need: featurep, boundp, fboundp - (if (not (fboundp 'c-mode)) - - ;; We should provide a standard function for this boilerplate, - ;; probably called `Skip-Test' -- check for that API with C-h f - (let* ((reason "c-mode unavailable") - (count (gethash reason skipped-test-reasons))) - (puthash reason (if (null count) 1 (1+ count)) - skipped-test-reasons) - (Print-Skip "comment and parse-partial-sexp tests" reason)) - - ;; and here's the test code - (c-mode) - (insert "// comment\n") - (forward-comment -2) - (Assert (eq (point) (point-min))) - (let ((point (point))) - (insert "/* comment */") - (goto-char point) - (forward-comment 2) - (Assert (eq (point) (point-max))) - (parse-partial-sexp point (point-max))))) - - `Skip-Test' is intended for use with features that are normally -present in typical configurations. For truly optional features, or -tests that apply to one of several alternative implementations (eg, to -GTK widgets, but not Athena, Motif, MS Windows, or Carbon), simply -silently omit the test. - - -File: internals.info, Node: A Summary of the Various XEmacs Modules, Next: Allocation of Objects in XEmacs Lisp, Prev: Regression Testing XEmacs, Up: Top - -A Summary of the Various XEmacs Modules -*************************************** - - This is accurate as of XEmacs 20.0. - -* Menu: - -* Low-Level Modules:: -* Basic Lisp Modules:: -* Modules for Standard Editing Operations:: -* Editor-Level Control Flow Modules:: -* Modules for the Basic Displayable Lisp Objects:: -* Modules for other Display-Related Lisp Objects:: -* Modules for the Redisplay Mechanism:: -* Modules for Interfacing with the File System:: -* Modules for Other Aspects of the Lisp Interpreter and Object System:: -* Modules for Interfacing with the Operating System:: -* Modules for Interfacing with X Windows:: -* Modules for Internationalization:: -* Modules for Regression Testing:: - - -File: internals.info, Node: Low-Level Modules, Next: Basic Lisp Modules, Up: A Summary of the Various XEmacs Modules - -Low-Level Modules -================= - - config.h - - This is automatically generated from `config.h.in' based on the -results of configure tests and user-selected optional features and -contains preprocessor definitions specifying the nature of the -environment in which XEmacs is being compiled. - - paths.h - - This is automatically generated from `paths.h.in' based on supplied -configure values, and allows for non-standard installed configurations -of the XEmacs directories. It's currently broken, though. - - emacs.c - signal.c - - `emacs.c' contains `main()' and other code that performs the most -basic environment initializations and handles shutting down the XEmacs -process (this includes `kill-emacs', the normal way that XEmacs is -exited; `dump-emacs', which is used during the build process to write -out the XEmacs executable; `run-emacs-from-temacs', which can be used -to start XEmacs directly when temacs has finished loading all the Lisp -code; and emergency code to handle crashes [XEmacs tries to auto-save -all files before it crashes]). - - Low-level code that directly interacts with the Unix signal -mechanism, however, is in `signal.c'. Note that this code does not -handle system dependencies in interfacing to signals; that is handled -using the `syssignal.h' header file, described in section J below. - - unexaix.c - unexalpha.c - unexapollo.c - unexconvex.c - unexec.c - unexelf.c - unexelfsgi.c - unexencap.c - unexenix.c - unexfreebsd.c - unexfx2800.c - unexhp9k3.c - unexhp9k800.c - unexmips.c - unexnext.c - unexsol2.c - unexsunos4.c - - These modules contain code dumping out the XEmacs executable on -various different systems. (This process is highly machine-specific and -requires intimate knowledge of the executable format and the memory map -of the process.) Only one of these modules is actually used; this is -chosen by `configure'. - - ecrt0.c - lastfile.c - pre-crt0.c - - These modules are used in conjunction with the dump mechanism. On -some systems, an alternative version of the C startup code (the actual -code that receives control from the operating system when the process is -started, and which calls `main()') is required so that the dumping -process works properly; `crt0.c' provides this. - - `pre-crt0.c' and `lastfile.c' should be the very first and very last -file linked, respectively. (Actually, this is not really true. -`lastfile.c' should be after all Emacs modules whose initialized data -should be made constant, and before all other Emacs files and all -libraries. In particular, the allocation modules `gmalloc.c', -`alloca.c', etc. are normally placed past `lastfile.c', and all of the -files that implement Xt widget classes _must_ be placed after -`lastfile.c' because they contain various structures that must be -statically initialized and into which Xt writes at various times.) -`pre-crt0.c' and `lastfile.c' contain exported symbols that are used to -determine the start and end of XEmacs' initialized data space when -dumping. - - alloca.c - free-hook.c - getpagesize.h - gmalloc.c - malloc.c - mem-limits.h - ralloc.c - vm-limit.c - - These handle basic C allocation of memory. `alloca.c' is an -emulation of the stack allocation function `alloca()' on machines that -lack this. (XEmacs makes extensive use of `alloca()' in its code.) - - `gmalloc.c' and `malloc.c' are two implementations of the standard C -functions `malloc()', `realloc()' and `free()'. They are often used in -place of the standard system-provided `malloc()' because they usually -provide a much faster implementation, at the expense of additional -memory use. `gmalloc.c' is a newer implementation that is much more -memory-efficient for large allocations than `malloc.c', and should -always be preferred if it works. (At one point, `gmalloc.c' didn't work -on some systems where `malloc.c' worked; but this should be fixed now.) - - `ralloc.c' is the "relocating allocator". It provides functions -similar to `malloc()', `realloc()' and `free()' that allocate memory -that can be dynamically relocated in memory. The advantage of this is -that allocated memory can be shuffled around to place all the free -memory at the end of the heap, and the heap can then be shrunk, -releasing the memory back to the operating system. The use of this can -be controlled with the configure option `--rel-alloc'; if enabled, -memory allocated for buffers will be relocatable, so that if a very -large file is visited and the buffer is later killed, the memory can be -released to the operating system. (The disadvantage of this mechanism -is that it can be very slow. On systems with the `mmap()' system call, -the XEmacs version of `ralloc.c' uses this to move memory around -without actually having to block-copy it, which can speed things up; -but it can still cause noticeable performance degradation.) - - `free-hook.c' contains some debugging functions for checking for -invalid arguments to `free()'. - - `vm-limit.c' contains some functions that warn the user when memory -is getting low. These are callback functions that are called by -`gmalloc.c' and `malloc.c' at appropriate times. - - `getpagesize.h' provides a uniform interface for retrieving the size -of a page in virtual memory. `mem-limits.h' provides a uniform -interface for retrieving the total amount of available virtual memory. -Both are similar in spirit to the `sys*.h' files described in section -J, below. - - blocktype.c - blocktype.h - dynarr.c - - These implement a couple of basic C data types to facilitate memory -allocation. The `Blocktype' type efficiently manages the allocation of -fixed-size blocks by minimizing the number of times that `malloc()' and -`free()' are called. It allocates memory in large chunks, subdivides -the chunks into blocks of the proper size, and returns the blocks as -requested. When blocks are freed, they are placed onto a linked list, -so they can be efficiently reused. This data type is not much used in -XEmacs currently, because it's a fairly new addition. - - The `Dynarr' type implements a "dynamic array", which is similar to -a standard C array but has no fixed limit on the number of elements it -can contain. Dynamic arrays can hold elements of any type, and when -you add a new element, the array automatically resizes itself if it -isn't big enough. Dynarrs are extensively used in the redisplay -mechanism. - - inline.c - - This module is used in connection with inline functions (available in -some compilers). Often, inline functions need to have a corresponding -non-inline function that does the same thing. This module is where they -reside. It contains no actual code, but defines some special flags that -cause inline functions defined in header files to be rendered as actual -functions. It then includes all header files that contain any inline -function definitions, so that each one gets a real function equivalent. - - debug.c - debug.h - - These functions provide a system for doing internal consistency -checks during code development. This system is not currently used; -instead the simpler `assert()' macro is used along with the various -checks provided by the `--error-check-*' configuration options. - - universe.h - - This is not currently used. - - -File: internals.info, Node: Basic Lisp Modules, Next: Modules for Standard Editing Operations, Prev: Low-Level Modules, Up: A Summary of the Various XEmacs Modules - -Basic Lisp Modules -================== - - lisp-disunion.h - lisp-union.h - lisp.h - lrecord.h - symsinit.h - - These are the basic header files for all XEmacs modules. Each module -includes `lisp.h', which brings the other header files in. `lisp.h' -contains the definitions of the structures and extractor and -constructor macros for the basic Lisp objects and various other basic -definitions for the Lisp environment, as well as some general-purpose -definitions (e.g. `min()' and `max()'). `lisp.h' includes either -`lisp-disunion.h' or `lisp-union.h', depending on whether -`USE_UNION_TYPE' is defined. These files define the typedef of the -Lisp object itself (as described above) and the low-level macros that -hide the actual implementation of the Lisp object. All extractor and -constructor macros for particular types of Lisp objects are defined in -terms of these low-level macros. - - As a general rule, all typedefs should go into the typedefs section -of `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 be placed into other header files. Forward structure -declarations (i.e. a simple declaration like `struct foo;' where the -structure itself is defined elsewhere) should be placed into the -typedefs section as necessary. - - `lrecord.h' contains the basic structures and macros that implement -all record-type Lisp objects--i.e. all objects whose type is a field in -their C structure, which includes all objects except the few most basic -ones. - - `lisp.h' contains prototypes for most of the exported functions in -the various modules. Lisp primitives defined using `DEFUN' that need -to be called by C code should be declared using `EXFUN'. Other -function prototypes should be placed either into the appropriate -section of `lisp.h', or into a module-specific header file, depending -on how general-purpose the function is and whether it has -special-purpose argument types requiring definitions not in `lisp.h'.) -All initialization functions are prototyped in `symsinit.h'. - - alloc.c - - The large module `alloc.c' implements all of the basic allocation and -garbage collection for Lisp objects. The most commonly used Lisp -objects are allocated in chunks, similar to the Blocktype data type -described above; others are allocated in individually `malloc()'ed -blocks. This module provides the foundation on which all other aspects -of the Lisp environment sit, and is the first module initialized at -startup. - - Note that `alloc.c' provides a series of generic functions that are -not dependent on any particular object type, and interfaces to -particular types of objects using a standardized interface of -type-specific methods. This scheme is a fundamental principle of -object-oriented programming and is heavily used throughout XEmacs. The -great advantage of this is that it allows for a clean separation of -functionality into different modules--new classes of Lisp objects, new -event interfaces, new device types, new stream interfaces, etc. can be -added transparently without affecting code anywhere else in XEmacs. -Because the different subsystems are divided into general and specific -code, adding a new subtype within a subsystem will in general not -require changes to the generic subsystem code or affect any of the other -subtypes in the subsystem; this provides a great deal of robustness to -the XEmacs code. - - eval.c - backtrace.h - - This module contains all of the functions to handle the flow of -control. This includes the mechanisms of defining functions, calling -functions, traversing stack frames, and binding variables; the control -primitives and other special forms such as `while', `if', `eval', -`let', `and', `or', `progn', etc.; handling of non-local exits, -unwind-protects, and exception handlers; entering the debugger; methods -for the subr Lisp object type; etc. It does _not_ include the `read' -function, the `print' function, or the handling of symbols and obarrays. - - `backtrace.h' contains some structures related to stack frames and -the flow of control. - - lread.c - - This module implements the Lisp reader and the `read' function, -which converts text into Lisp objects, according to the read syntax of -the objects, as described above. This is similar to the parser that is -a part of all compilers. - - print.c - - This module implements the Lisp print mechanism and the `print' -function and related functions. This is the inverse of the Lisp reader -- it converts Lisp objects to a printed, textual representation. -(Hopefully something that can be read back in using `read' to get an -equivalent object.) - - general.c - symbols.c - symeval.h - - `symbols.c' implements the handling of symbols, obarrays, and -retrieving the values of symbols. Much of the code is devoted to -handling the special "symbol-value-magic" objects that define special -types of variables--this includes buffer-local variables, variable -aliases, variables that forward into C variables, etc. This module is -initialized extremely early (right after `alloc.c'), because it is here -that the basic symbols `t' and `nil' are created, and those symbols are -used everywhere throughout XEmacs. - - `symeval.h' contains the definitions of symbol structures and the -`DEFVAR_LISP()' and related macros for declaring variables. - - data.c - floatfns.c - fns.c - - These modules implement the methods and standard Lisp primitives for -all the basic Lisp object types other than symbols (which are described -above). `data.c' contains all the predicates (primitives that return -whether an object is of a particular type); the integer arithmetic -functions; and the basic accessor and mutator primitives for the various -object types. `fns.c' contains all the standard predicates for working -with sequences (where, abstractly speaking, a sequence is an ordered set -of objects, and can be represented by a list, string, vector, or -bit-vector); it also contains `equal', perhaps on the grounds that bulk -of the operation of `equal' is comparing sequences. `floatfns.c' -contains methods and primitives for floats and floating-point -arithmetic. - - bytecode.c - bytecode.h - - `bytecode.c' implements the byte-code interpreter and -compiled-function objects, and `bytecode.h' contains associated -structures. Note that the byte-code _compiler_ is written in Lisp. - diff -u -r -N xemacs-21.4.14/info/internals.info-4 xemacs-21.4.15/info/internals.info-4 --- xemacs-21.4.14/info/internals.info-4 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-4 1969-12-31 19:00:00.000000000 -0500 @@ -1,1182 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Modules for Standard Editing Operations, Next: Editor-Level Control Flow Modules, Prev: Basic Lisp Modules, Up: A Summary of the Various XEmacs Modules - -Modules for Standard Editing Operations -======================================= - - buffer.c - buffer.h - bufslots.h - - `buffer.c' implements the "buffer" Lisp object type. This includes -functions that create and destroy buffers; retrieve buffers by name or -by other properties; manipulate lists of buffers (remember that buffers -are permanent objects and stored in various ordered lists); retrieve or -change buffer properties; etc. It also contains the definitions of all -the built-in buffer-local variables (which can be viewed as buffer -properties). It does _not_ contain code to manipulate buffer-local -variables (that's in `symbols.c', described above); or code to -manipulate the text in a buffer. - - `buffer.h' defines the structures associated with a buffer and the -various macros for retrieving text from a buffer and special buffer -positions (e.g. `point', the default location for text insertion). It -also contains macros for working with buffer positions and converting -between their representations as character offsets and as byte offsets -(under MULE, they are different, because characters can be multi-byte). -It is one of the largest header files. - - `bufslots.h' defines the fields in the buffer structure that -correspond to the built-in buffer-local variables. It is its own -header file because it is included many times in `buffer.c', as a way -of iterating over all the built-in buffer-local variables. - - insdel.c - insdel.h - - `insdel.c' contains low-level functions for inserting and deleting -text in a buffer, keeping track of changed regions for use by -redisplay, and calling any before-change and after-change functions -that may have been registered for the buffer. It also contains the -actual functions that convert between byte offsets and character -offsets. - - `insdel.h' contains associated headers. - - marker.c - - This module implements the "marker" Lisp object type, which -conceptually is a pointer to a text position in a buffer that moves -around as text is inserted and deleted, so as to remain in the same -relative position. This module doesn't actually move the markers around -- that's handled in `insdel.c'. This module just creates them and -implements the primitives for working with them. As markers are simple -objects, this does not entail much. - - Note that the standard arithmetic primitives (e.g. `+') accept -markers in place of integers and automatically substitute the value of -`marker-position' for the marker, i.e. an integer describing the -current buffer position of the marker. - - extents.c - extents.h - - This module implements the "extent" Lisp object type, which is like -a marker that works over a range of text rather than a single position. -Extents are also much more complex and powerful than markers and have a -more efficient (and more algorithmically complex) implementation. The -implementation is described in detail in comments in `extents.c'. - - The code in `extents.c' works closely with `insdel.c' so that -extents are properly moved around as text is inserted and deleted. -There is also code in `extents.c' that provides information needed by -the redisplay mechanism for efficient operation. (Remember that extents -can have display properties that affect [sometimes drastically, as in -the `invisible' property] the display of the text they cover.) - - editfns.c - - `editfns.c' contains the standard Lisp primitives for working with a -buffer's text, and calls the low-level functions in `insdel.c'. It -also contains primitives for working with `point' (the default buffer -insertion location). - - `editfns.c' also contains functions for retrieving various -characteristics from the external environment: the current time, the -process ID of the running XEmacs process, the name of the user who ran -this XEmacs process, etc. It's not clear why this code is in -`editfns.c'. - - callint.c - cmds.c - commands.h - - These modules implement the basic "interactive" commands, i.e. -user-callable functions. Commands, as opposed to other functions, have -special ways of getting their parameters interactively (by querying the -user), as opposed to having them passed in a normal function -invocation. Many commands are not really meant to be called from other -Lisp functions, because they modify global state in a way that's often -undesired as part of other Lisp functions. - - `callint.c' implements the mechanism for querying the user for -parameters and calling interactive commands. The bulk of this module is -code that parses the interactive spec that is supplied with an -interactive command. - - `cmds.c' implements the basic, most commonly used editing commands: -commands to move around the current buffer and insert and delete -characters. These commands are implemented using the Lisp primitives -defined in `editfns.c'. - - `commands.h' contains associated structure definitions and -prototypes. - - regex.c - regex.h - search.c - - `search.c' implements the Lisp primitives for searching for text in -a buffer, and some of the low-level algorithms for doing this. In -particular, the fast fixed-string Boyer-Moore search algorithm is -implemented in `search.c'. The low-level algorithms for doing -regular-expression searching, however, are implemented in `regex.c' and -`regex.h'. These two modules are largely independent of XEmacs, and -are similar to (and based upon) the regular-expression routines used in -`grep' and other GNU utilities. - - doprnt.c - - `doprnt.c' implements formatted-string processing, similar to -`printf()' command in C. - - undo.c - - This module implements the undo mechanism for tracking buffer -changes. Most of this could be implemented in Lisp. - - -File: internals.info, Node: Editor-Level Control Flow Modules, Next: Modules for the Basic Displayable Lisp Objects, Prev: Modules for Standard Editing Operations, Up: A Summary of the Various XEmacs Modules - -Editor-Level Control Flow Modules -================================= - - event-Xt.c - event-msw.c - event-stream.c - event-tty.c - events-mod.h - gpmevent.c - gpmevent.h - events.c - events.h - - These implement the handling of events (user input and other system -notifications). - - `events.c' and `events.h' define the "event" Lisp object type and -primitives for manipulating it. - - `event-stream.c' implements the basic functions for working with -event queues, dispatching an event by looking it up in relevant keymaps -and such, and handling timeouts; this includes the primitives -`next-event' and `dispatch-event', as well as related primitives such -as `sit-for', `sleep-for', and `accept-process-output'. -(`event-stream.c' is one of the hairiest and trickiest modules in -XEmacs. Beware! You can easily mess things up here.) - - `event-Xt.c' and `event-tty.c' implement the low-level interfaces -onto retrieving events from Xt (the X toolkit) and from TTY's (using -`read()' and `select()'), respectively. The event interface enforces a -clean separation between the specific code for interfacing with the -operating system and the generic code for working with events, by -defining an API of basic, low-level event methods; `event-Xt.c' and -`event-tty.c' are two different implementations of this API. To add -support for a new operating system (e.g. NeXTstep), one merely needs to -provide another implementation of those API functions. - - Note that the choice of whether to use `event-Xt.c' or `event-tty.c' -is made at compile time! Or at the very latest, it is made at startup -time. `event-Xt.c' handles events for _both_ X and TTY frames; -`event-tty.c' is only used when X support is not compiled into XEmacs. -The reason for this is that there is only one event loop in XEmacs: -thus, it needs to be able to receive events from all different kinds of -frames. - - keymap.c - keymap.h - - `keymap.c' and `keymap.h' define the "keymap" Lisp object type and -associated methods and primitives. (Remember that keymaps are objects -that associate event descriptions with functions to be called to -"execute" those events; `dispatch-event' looks up events in the -relevant keymaps.) - - cmdloop.c - - `cmdloop.c' contains functions that implement the actual editor -command loop--i.e. the event loop that cyclically retrieves and -dispatches events. This code is also rather tricky, just like -`event-stream.c'. - - macros.c - macros.h - - These two modules contain the basic code for defining keyboard -macros. These functions don't actually do much; most of the code that -handles keyboard macros is mixed in with the event-handling code in -`event-stream.c'. - - minibuf.c - - This contains some miscellaneous code related to the minibuffer -(most of the minibuffer code was moved into Lisp by Richard Mlynarik). -This includes the primitives for completion (although filename -completion is in `dired.c'), the lowest-level interface to the -minibuffer (if the command loop were cleaned up, this too could be in -Lisp), and code for dealing with the echo area (this, too, was mostly -moved into Lisp, and the only code remaining is code to call out to -Lisp or provide simple bootstrapping implementations early in temacs, -before the echo-area Lisp code is loaded). - - -File: internals.info, Node: Modules for the Basic Displayable Lisp Objects, Next: Modules for other Display-Related Lisp Objects, Prev: Editor-Level Control Flow Modules, Up: A Summary of the Various XEmacs Modules - -Modules for the Basic Displayable Lisp Objects -============================================== - - console-msw.c - console-msw.h - console-stream.c - console-stream.h - console-tty.c - console-tty.h - console-x.c - console-x.h - console.c - console.h - - These modules implement the "console" Lisp object type. A console -contains multiple display devices, but only one keyboard and mouse. -Most of the time, a console will contain exactly one device. - - Consoles are the top of a lisp object inclusion hierarchy. Consoles -contain devices, which contain frames, which contain windows. - - device-msw.c - device-tty.c - device-x.c - device.c - device.h - - These modules implement the "device" Lisp object type. This -abstracts a particular screen or connection on which frames are -displayed. As with Lisp objects, event interfaces, and other -subsystems, the device code is separated into a generic component that -contains a standardized interface (in the form of a set of methods) onto -particular device types. - - The device subsystem defines all the methods and provides method -services for not only device operations but also for the frame, window, -menubar, scrollbar, toolbar, and other displayable-object subsystems. -The reason for this is that all of these subsystems have the same -subtypes (X, TTY, NeXTstep, Microsoft Windows, etc.) as devices do. - - frame-msw.c - frame-tty.c - frame-x.c - frame.c - frame.h - - Each device contains one or more frames in which objects (e.g. text) -are displayed. A frame corresponds to a window in the window system; -usually this is a top-level window but it could potentially be one of a -number of overlapping child windows within a top-level window, using the -MDI (Multiple Document Interface) protocol in Microsoft Windows or a -similar scheme. - - The `frame-*' files implement the "frame" Lisp object type and -provide the generic and device-type-specific operations on frames (e.g. -raising, lowering, resizing, moving, etc.). - - window.c - window.h - - Each frame consists of one or more non-overlapping "windows" (better -known as "panes" in standard window-system terminology) in which a -buffer's text can be displayed. Windows can also have scrollbars -displayed around their edges. - - `window.c' and `window.h' implement the "window" Lisp object type -and provide code to manage windows. Since windows have no associated -resources in the window system (the window system knows only about the -frame; no child windows or anything are used for XEmacs windows), there -is no device-type-specific code here; all of that code is part of the -redisplay mechanism or the code for particular object types such as -scrollbars. - - -File: internals.info, Node: Modules for other Display-Related Lisp Objects, Next: Modules for the Redisplay Mechanism, Prev: Modules for the Basic Displayable Lisp Objects, Up: A Summary of the Various XEmacs Modules - -Modules for other Display-Related Lisp Objects -============================================== - - faces.c - faces.h - - bitmaps.h - glyphs-eimage.c - glyphs-msw.c - glyphs-msw.h - glyphs-widget.c - glyphs-x.c - glyphs-x.h - glyphs.c - glyphs.h - - objects-msw.c - objects-msw.h - objects-tty.c - objects-tty.h - objects-x.c - objects-x.h - objects.c - objects.h - - menubar-msw.c - menubar-msw.h - menubar-x.c - menubar.c - menubar.h - - scrollbar-msw.c - scrollbar-msw.h - scrollbar-x.c - scrollbar-x.h - scrollbar.c - scrollbar.h - - toolbar-msw.c - toolbar-x.c - toolbar.c - toolbar.h - - font-lock.c - - This file provides C support for syntax highlighting--i.e. -highlighting different syntactic constructs of a source file in -different colors, for easy reading. The C support is provided so that -this is fast. - - As of 21.4.10, bugs introduced at the very end of the 21.2 series in -the "syntax properties" code were fixed, and highlighting is acceptably -quick again. However, presumably more improvements are possible, and -the places to look are probably here, in the defun-traversing code, and -in `syntax.c', in the comment-traversing code. - - dgif_lib.c - gif_err.c - gif_lib.h - gifalloc.c - - These modules decode GIF-format image files, for use with glyphs. -These files were removed due to Unisys patent infringement concerns. - - -File: internals.info, Node: Modules for the Redisplay Mechanism, Next: Modules for Interfacing with the File System, Prev: Modules for other Display-Related Lisp Objects, Up: A Summary of the Various XEmacs Modules - -Modules for the Redisplay Mechanism -=================================== - - redisplay-output.c - redisplay-msw.c - redisplay-tty.c - redisplay-x.c - redisplay.c - redisplay.h - - These files provide the redisplay mechanism. As with many other -subsystems in XEmacs, there is a clean separation between the general -and device-specific support. - - `redisplay.c' contains the bulk of the redisplay engine. These -functions update the redisplay structures (which describe how the screen -is to appear) to reflect any changes made to the state of any -displayable objects (buffer, frame, window, etc.) since the last time -that redisplay was called. These functions are highly optimized to -avoid doing more work than necessary (since redisplay is called -extremely often and is potentially a huge time sink), and depend heavily -on notifications from the objects themselves that changes have occurred, -so that redisplay doesn't explicitly have to check each possible object. -The redisplay mechanism also contains a great deal of caching to further -speed things up; some of this caching is contained within the various -displayable objects. - - `redisplay-output.c' goes through the redisplay structures and -converts them into calls to device-specific methods to actually output -the screen changes. - - `redisplay-x.c' and `redisplay-tty.c' are two implementations of -these redisplay output methods, for X frames and TTY frames, -respectively. - - indent.c - - This module contains various functions and Lisp primitives for -converting between buffer positions and screen positions. These -functions call the redisplay mechanism to do most of the work, and then -examine the redisplay structures to get the necessary information. This -module needs work. - - termcap.c - terminfo.c - tparam.c - - These files contain functions for working with the termcap -(BSD-style) and terminfo (System V style) databases of terminal -capabilities and escape sequences, used when XEmacs is displaying in a -TTY. - - cm.c - cm.h - - These files provide some miscellaneous TTY-output functions and -should probably be merged into `redisplay-tty.c'. - - -File: internals.info, Node: Modules for Interfacing with the File System, Next: Modules for Other Aspects of the Lisp Interpreter and Object System, Prev: Modules for the Redisplay Mechanism, Up: A Summary of the Various XEmacs Modules - -Modules for Interfacing with the File System -============================================ - - lstream.c - lstream.h - - These modules implement the "stream" Lisp object type. This is an -internal-only Lisp object that implements a generic buffering stream. -The idea is to provide a uniform interface onto all sources and sinks of -data, including file descriptors, stdio streams, chunks of memory, Lisp -buffers, Lisp strings, etc. That way, I/O functions can be written to -the stream interface and can transparently handle all possible sources -and sinks. (For example, the `read' function can read data from a -file, a string, a buffer, or even a function that is called repeatedly -to return data, without worrying about where the data is coming from or -what-size chunks it is returned in.) - - Note that in the C code, streams are called "lstreams" (for "Lisp -streams") to distinguish them from other kinds of streams, e.g. stdio -streams and C++ I/O streams. - - Similar to other subsystems in XEmacs, lstreams are separated into -generic functions and a set of methods for the different types of -lstreams. `lstream.c' provides implementations of many different types -of streams; others are provided, e.g., in `file-coding.c'. - - fileio.c - - This implements the basic primitives for interfacing with the file -system. This includes primitives for reading files into buffers, -writing buffers into files, checking for the presence or accessibility -of files, canonicalizing file names, etc. Note that these primitives -are usually not invoked directly by the user: There is a great deal of -higher-level Lisp code that implements the user commands such as -`find-file' and `save-buffer'. This is similar to the distinction -between the lower-level primitives in `editfns.c' and the higher-level -user commands in `commands.c' and `simple.el'. - - filelock.c - - This file provides functions for detecting clashes between different -processes (e.g. XEmacs and some external process, or two different -XEmacs processes) modifying the same file. (XEmacs can optionally use -the `lock/' subdirectory to provide a form of "locking" between -different XEmacs processes.) This module is also used by the low-level -functions in `insdel.c' to ensure that, if the first modification is -being made to a buffer whose corresponding file has been externally -modified, the user is made aware of this so that the buffer can be -synched up with the external changes if necessary. - - filemode.c - - This file provides some miscellaneous functions that construct a -`rwxr-xr-x'-type permissions string (as might appear in an `ls'-style -directory listing) given the information returned by the `stat()' -system call. - - dired.c - ndir.h - - These files implement the XEmacs interface to directory searching. -This includes a number of primitives for determining the files in a -directory and for doing filename completion. (Remember that generic -completion is handled by a different mechanism, in `minibuf.c'.) - - `ndir.h' is a header file used for the directory-searching emulation -functions provided in `sysdep.c' (see section J below), for systems -that don't provide any directory-searching functions. (On those -systems, directories can be read directly as files, and parsed.) - - realpath.c - - This file provides an implementation of the `realpath()' function -for expanding symbolic links, on systems that don't implement it or have -a broken implementation. - - -File: internals.info, Node: Modules for Other Aspects of the Lisp Interpreter and Object System, Next: Modules for Interfacing with the Operating System, Prev: Modules for Interfacing with the File System, Up: A Summary of the Various XEmacs Modules - -Modules for Other Aspects of the Lisp Interpreter and Object System -=================================================================== - - elhash.c - elhash.h - hash.c - hash.h - - These files provide two implementations of hash tables. Files -`hash.c' and `hash.h' provide a generic C implementation of hash tables -which can stand independently of XEmacs. Files `elhash.c' and -`elhash.h' provide a separate implementation of hash tables that can -store only Lisp objects, and knows about Lispy things like garbage -collection, and implement the "hash-table" Lisp object type. - - specifier.c - specifier.h - - This module implements the "specifier" Lisp object type. This is -primarily used for displayable properties, and allows for values that -are specific to a particular buffer, window, frame, device, or device -class, as well as a default value existing. This is used, for example, -to control the height of the horizontal scrollbar or the appearance of -the `default', `bold', or other faces. The specifier object consists -of a number of specifications, each of which maps from a buffer, -window, etc. to a value. The function `specifier-instance' looks up a -value given a window (from which a buffer, frame, and device can be -derived). - - chartab.c - chartab.h - casetab.c - - `chartab.c' and `chartab.h' implement the "char table" Lisp object -type, which maps from characters or certain sorts of character ranges -to Lisp objects. The implementation of this object type is optimized -for the internal representation of characters. Char tables come in -different types, which affect the allowed object types to which a -character can be mapped and also dictate certain other properties of -the char table. - - `casetab.c' implements one sort of char table, the "case table", -which maps characters to other characters of possibly different case. -These are used by XEmacs to implement case-changing primitives and to -do case-insensitive searching. - - syntax.c - syntax.h - - This module implements "syntax tables", another sort of char table -that maps characters into syntax classes that define the syntax of these -characters (e.g. a parenthesis belongs to a class of `open' characters -that have corresponding `close' characters and can be nested). This -module also implements the Lisp "scanner", a set of primitives for -scanning over text based on syntax tables. This is used, for example, -to find the matching parenthesis in a command such as `forward-sexp', -and by `font-lock.c' to locate quoted strings, comments, etc. - - Syntax codes are implemented as bitfields in an int. Bits 0-6 -contain the syntax code itself, bit 7 is a special prefix flag used for -Lisp, and bits 16-23 contain comment syntax flags. From the Lisp -programmer's point of view, there are 11 flags: 2 styles X 2 characters -X {start, end} flags for two-character comment delimiters, 2 style -flags for one-character comment delimiters, and the prefix flag. - - Internally, however, the characters used in multi-character -delimiters will have non-comment-character syntax classes (_e.g._, the -`/' in C's `/*' comment-start delimiter has "punctuation" (here meaning -"operator-like") class in C modes). Thus in a mixed comment style, -such as C++'s `//' to end of line, is represented by giving `/' the -"punctuation" class and the "style b first character of start sequence" -and "style b second character of start sequence" flags. The fact that -class is _not_ punctuation allows the syntax scanner to recognize that -this is a multi-character delimiter. The `newline' character is given -(single-character) "comment-end" _class_ and the "style b first -character of end sequence" _flag_. The "comment-end" class allows the -scanner to determine that no second character is needed to terminate -the comment. - - casefiddle.c - - This module implements various Lisp primitives for upcasing, -downcasing and capitalizing strings or regions of buffers. - - rangetab.c - - This module implements the "range table" Lisp object type, which -provides for a mapping from ranges of integers to arbitrary Lisp -objects. - - opaque.c - opaque.h - - This module implements the "opaque" Lisp object type, an -internal-only Lisp object that encapsulates an arbitrary block of memory -so that it can be managed by the Lisp allocation system. To create an -opaque object, you call `make_opaque()', passing a pointer to a block -of memory. An object is created that is big enough to hold the memory, -which is copied into the object's storage. The object will then stick -around as long as you keep pointers to it, after which it will be -automatically reclaimed. - - Opaque objects can also have an arbitrary "mark method" associated -with them, in case the block of memory contains other Lisp objects that -need to be marked for garbage-collection purposes. (If you need other -object methods, such as a finalize method, you should just go ahead and -create a new Lisp object type--it's not hard.) - - abbrev.c - - This function provides a few primitives for doing dynamic -abbreviation expansion. In XEmacs, most of the code for this has been -moved into Lisp. Some C code remains for speed and because the -primitive `self-insert-command' (which is executed for all -self-inserting characters) hooks into the abbrev mechanism. -(`self-insert-command' is itself in C only for speed.) - - doc.c - - This function provides primitives for retrieving the documentation -strings of functions and variables. These documentation strings contain -certain special markers that get dynamically expanded (e.g. a -reverse-lookup is performed on some named functions to retrieve their -current key bindings). Some documentation strings (in particular, for -the built-in primitives and pre-loaded Lisp functions) are stored -externally in a file `DOC' in the `lib-src/' directory and need to be -fetched from that file. (Part of the build stage involves building this -file, and another part involves constructing an index for this file and -embedding it into the executable, so that the functions in `doc.c' do -not have to search the entire `DOC' file to find the appropriate -documentation string.) - - md5.c - - This function provides a Lisp primitive that implements the MD5 -secure hashing scheme, used to create a large hash value of a string of -data such that the data cannot be derived from the hash value. This is -used for various security applications on the Internet. - - -File: internals.info, Node: Modules for Interfacing with the Operating System, Next: Modules for Interfacing with X Windows, Prev: Modules for Other Aspects of the Lisp Interpreter and Object System, Up: A Summary of the Various XEmacs Modules - -Modules for Interfacing with the Operating System -================================================= - - callproc.c - process.c - process.h - - These modules allow XEmacs to spawn and communicate with subprocesses -and network connections. - - `callproc.c' implements (through the `call-process' primitive) what -are called "synchronous subprocesses". This means that XEmacs runs a -program, waits till it's done, and retrieves its output. A typical -example might be calling the `ls' program to get a directory listing. - - `process.c' and `process.h' implement "asynchronous subprocesses". -This means that XEmacs starts a program and then continues normally, -not waiting for the process to finish. Data can be sent to the process -or retrieved from it as it's running. This is used for the `shell' -command (which provides a front end onto a shell program such as -`csh'), the mail and news readers implemented in XEmacs, etc. The -result of calling `start-process' to start a subprocess is a process -object, a particular kind of object used to communicate with the -subprocess. You can send data to the process by passing the process -object and the data to `send-process', and you can specify what happens -to data retrieved from the process by setting properties of the process -object. (When the process sends data, XEmacs receives a process event, -which says that there is data ready. When `dispatch-event' is called -on this event, it reads the data from the process and does something -with it, as specified by the process object's properties. Typically, -this means inserting the data into a buffer or calling a function.) -Another property of the process object is called the "sentinel", which -is a function that is called when the process terminates. - - Process objects are also used for network connections (connections -to a process running on another machine). Network connections are -started with `open-network-stream' but otherwise work just like -subprocesses. - - sysdep.c - sysdep.h - - These modules implement most of the low-level, messy operating-system -interface code. This includes various device control (ioctl) operations -for file descriptors, TTY's, pseudo-terminals, etc. (usually this stuff -is fairly system-dependent; thus the name of this module), and emulation -of standard library functions and system calls on systems that don't -provide them or have broken versions. - - sysdir.h - sysfile.h - sysfloat.h - sysproc.h - syspwd.h - syssignal.h - systime.h - systty.h - syswait.h - - These header files provide consistent interfaces onto -system-dependent header files and system calls. The idea is that, -instead of including a standard header file like `' (which -may or may not exist on various systems) or having to worry about -whether all system provide a particular preprocessor constant, or -having to deal with the four different paradigms for manipulating -signals, you just include the appropriate `sys*.h' header file, which -includes all the right system header files, defines and missing -preprocessor constants, provides a uniform interface onto system calls, -etc. - - `sysdir.h' provides a uniform interface onto directory-querying -functions. (In some cases, this is in conjunction with emulation -functions in `sysdep.c'.) - - `sysfile.h' includes all the necessary header files for standard -system calls (e.g. `read()'), ensures that all necessary `open()' and -`stat()' preprocessor constants are defined, and possibly (usually) -substitutes sugared versions of `read()', `write()', etc. that -automatically restart interrupted I/O operations. - - `sysfloat.h' includes the necessary header files for floating-point -operations. - - `sysproc.h' includes the necessary header files for calling -`select()', `fork()', `execve()', socket operations, and the like, and -ensures that the `FD_*()' macros for descriptor-set manipulations are -available. - - `syspwd.h' includes the necessary header files for obtaining -information from `/etc/passwd' (the functions are emulated under VMS). - - `syssignal.h' includes the necessary header files for -signal-handling and provides a uniform interface onto the different -signal-handling and signal-blocking paradigms. - - `systime.h' includes the necessary header files and provides uniform -interfaces for retrieving the time of day, setting file -access/modification times, getting the amount of time used by the XEmacs -process, etc. - - `systty.h' buffers against the infinitude of different ways of -controlling TTY's. - - `syswait.h' provides a uniform way of retrieving the exit status -from a `wait()'ed-on process (some systems use a union, others use an -int). - - hpplay.c - libsst.c - libsst.h - libst.h - linuxplay.c - nas.c - sgiplay.c - sound.c - sunplay.c - - These files implement the ability to play various sounds on some -types of computers. You have to configure your XEmacs with sound -support in order to get this capability. - - `sound.c' provides the generic interface. It implements various -Lisp primitives and variables that let you specify which sounds should -be played in certain conditions. (The conditions are identified by -symbols, which are passed to `ding' to make a sound. Various standard -functions call this function at certain times; if sound support does -not exist, a simple beep results. - - `sgiplay.c', `sunplay.c', `hpplay.c', and `linuxplay.c' interface to -the machine's speaker for various different kind of machines. This is -called "native" sound. - - `nas.c' interfaces to a computer somewhere else on the network using -the NAS (Network Audio Server) protocol, playing sounds on that -machine. This allows you to run XEmacs on a remote machine, with its -display set to your local machine, and have the sounds be made on your -local machine, provided that you have a NAS server running on your local -machine. - - `libsst.c', `libsst.h', and `libst.h' provide some additional -functions for playing sound on a Sun SPARC but are not currently in use. - - tooltalk.c - tooltalk.h - - These two modules implement an interface to the ToolTalk protocol, -which is an interprocess communication protocol implemented on some -versions of Unix. ToolTalk is a high-level protocol that allows -processes to register themselves as providers of particular services; -other processes can then request a service without knowing or caring -exactly who is providing the service. It is similar in spirit to the -DDE protocol provided under Microsoft Windows. ToolTalk is a part of -the new CDE (Common Desktop Environment) specification and is used to -connect the parts of the SPARCWorks development environment. - - getloadavg.c - - This module provides the ability to retrieve the system's current -load average. (The way to do this is highly system-specific, -unfortunately, and requires a lot of special-case code.) - - sunpro.c - - This module provides a small amount of code used internally at Sun to -keep statistics on the usage of XEmacs. - - broken-sun.h - strcmp.c - strcpy.c - sunOS-fix.c - - These files provide replacement functions and prototypes to fix -numerous bugs in early releases of SunOS 4.1. - - hftctl.c - - This module provides some terminal-control code necessary on -versions of AIX prior to 4.1. - - -File: internals.info, Node: Modules for Interfacing with X Windows, Next: Modules for Internationalization, Prev: Modules for Interfacing with the Operating System, Up: A Summary of the Various XEmacs Modules - -Modules for Interfacing with X Windows -====================================== - - Emacs.ad.h - - A file generated from `Emacs.ad', which contains XEmacs-supplied -fallback resources (so that XEmacs has pretty defaults). - - EmacsFrame.c - EmacsFrame.h - EmacsFrameP.h - - These modules implement an Xt widget class that encapsulates a frame. -This is for ease in integrating with Xt. The EmacsFrame widget covers -the entire X window except for the menubar; the scrollbars are -positioned on top of the EmacsFrame widget. - - *Warning:* Abandon hope, all ye who enter here. This code took an -ungodly amount of time to get right, and is likely to fall apart -mercilessly at the slightest change. Such is life under Xt. - - EmacsManager.c - EmacsManager.h - EmacsManagerP.h - - These modules implement a simple Xt manager (i.e. composite) widget -class that simply lets its children set whatever geometry they want. -It's amazing that Xt doesn't provide this standardly, but on second -thought, it makes sense, considering how amazingly broken Xt is. - - EmacsShell-sub.c - EmacsShell.c - EmacsShell.h - EmacsShellP.h - - These modules implement two Xt widget classes that are subclasses of -the TopLevelShell and TransientShell classes. This is necessary to deal -with more brokenness that Xt has sadistically thrust onto the backs of -developers. - - xgccache.c - xgccache.h - - These modules provide functions for maintenance and caching of GC's -(graphics contexts) under the X Window System. This code is junky and -needs to be rewritten. - - select-msw.c - select-x.c - select.c - select.h - - This module provides an interface to the X Window System's concept of -"selections", the standard way for X applications to communicate with -each other. - - xintrinsic.h - xintrinsicp.h - xmmanagerp.h - xmprimitivep.h - - These header files are similar in spirit to the `sys*.h' files and -buffer against different implementations of Xt and Motif. - - * `xintrinsic.h' should be included in place of `'. - - * `xintrinsicp.h' should be included in place of `'. - - * `xmmanagerp.h' should be included in place of `'. - - * `xmprimitivep.h' should be included in place of `'. - - xmu.c - xmu.h - - These files provide an emulation of the Xmu library for those systems -(i.e. HPUX) that don't provide it as a standard part of X. - - ExternalClient-Xlib.c - ExternalClient.c - ExternalClient.h - ExternalClientP.h - ExternalShell.c - ExternalShell.h - ExternalShellP.h - extw-Xlib.c - extw-Xlib.h - extw-Xt.c - extw-Xt.h - - These files provide the "external widget" interface, which allows an -XEmacs frame to appear as a widget in another application. To do this, -you have to configure with `--external-widget'. - - `ExternalShell*' provides the server (XEmacs) side of the connection. - - `ExternalClient*' provides the client (other application) side of -the connection. These files are not compiled into XEmacs but are -compiled into libraries that are then linked into your application. - - `extw-*' is common code that is used for both the client and server. - - Don't touch this code; something is liable to break if you do. - - -File: internals.info, Node: Modules for Internationalization, Next: Modules for Regression Testing, Prev: Modules for Interfacing with X Windows, Up: A Summary of the Various XEmacs Modules - -Modules for Internationalization -================================ - - mule-canna.c - mule-ccl.c - mule-charset.c - mule-charset.h - file-coding.c - file-coding.h - mule-mcpath.c - mule-mcpath.h - mule-wnnfns.c - mule.c - - These files implement the MULE (Asian-language) support. Note that -MULE actually provides a general interface for all sorts of languages, -not just Asian languages (although they are generally the most -complicated to support). This code is still in beta. - - `mule-charset.*' and `file-coding.*' provide the heart of the XEmacs -MULE support. `mule-charset.*' implements the "charset" Lisp object -type, which encapsulates a character set (an ordered one- or -two-dimensional set of characters, such as US ASCII or JISX0208 Japanese -Kanji). - - `file-coding.*' implements the "coding-system" Lisp object type, -which encapsulates a method of converting between different encodings. -An encoding is a representation of a stream of characters, possibly -from multiple character sets, using a stream of bytes or words, and -defines (e.g.) which escape sequences are used to specify particular -character sets, how the indices for a character are converted into bytes -(sometimes this involves setting the high bit; sometimes complicated -rearranging of the values takes place, as in the Shift-JIS encoding), -etc. - - `mule-ccl.c' provides the CCL (Code Conversion Language) -interpreter. CCL is similar in spirit to Lisp byte code and is used to -implement converters for custom encodings. - - `mule-canna.c' and `mule-wnnfns.c' implement interfaces to external -programs used to implement the Canna and WNN input methods, -respectively. This is currently in beta. - - `mule-mcpath.c' provides some functions to allow for pathnames -containing extended characters. This code is fragmentary, obsolete, and -completely non-working. Instead, PATHNAME-CODING-SYSTEM is used to -specify conversions of names of files and directories. The standard C -I/O functions like `open()' are wrapped so that conversion occurs -automatically. - - `mule.c' provides a few miscellaneous things that should probably be -elsewhere. - - intl.c - - This provides some miscellaneous internationalization code for -implementing message translation and interfacing to the Ximp input -method. None of this code is currently working. - - iso-wide.h - - This contains leftover code from an earlier implementation of -Asian-language support, and is not currently used. - - -File: internals.info, Node: Modules for Regression Testing, Prev: Modules for Internationalization, Up: A Summary of the Various XEmacs Modules - -Modules for Regression Testing -============================== - - test-harness.el - base64-tests.el - byte-compiler-tests.el - case-tests.el - ccl-tests.el - c-tests.el - database-tests.el - extent-tests.el - hash-table-tests.el - lisp-tests.el - md5-tests.el - mule-tests.el - regexp-tests.el - symbol-tests.el - syntax-tests.el - - `test-harness.el' defines the macros `Assert', `Check-Error', -`Check-Error-Message', and `Check-Message'. The other files are test -files, testing various XEmacs modules. - - -File: internals.info, Node: Allocation of Objects in XEmacs Lisp, Next: Dumping, Prev: A Summary of the Various XEmacs Modules, Up: Top - -Allocation of Objects in XEmacs Lisp -************************************ - -* Menu: - -* Introduction to Allocation:: -* Garbage Collection:: -* GCPROing:: -* Garbage Collection - Step by Step:: -* Integers and Characters:: -* Allocation from Frob Blocks:: -* lrecords:: -* Low-level allocation:: -* Cons:: -* Vector:: -* Bit Vector:: -* Symbol:: -* Marker:: -* String:: -* Compiled Function:: - - -File: internals.info, Node: Introduction to Allocation, Next: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp - -Introduction to Allocation -========================== - - Emacs Lisp, like all Lisps, has garbage collection. This means that -the programmer never has to explicitly free (destroy) an object; it -happens automatically when the object becomes inaccessible. Most -experts agree that garbage collection is a necessity in a modern, -high-level language. Its omission from C stems from the fact that C was -originally designed to be a nice abstract layer on top of assembly -language, for writing kernels and basic system utilities rather than -large applications. - - Lisp objects can be created by any of a number of Lisp primitives. -Most object types have one or a small number of basic primitives for -creating objects. For conses, the basic primitive is `cons'; for -vectors, the primitives are `make-vector' and `vector'; for symbols, -the primitives are `make-symbol' and `intern'; etc. Some Lisp objects, -especially those that are primarily used internally, have no -corresponding Lisp primitives. Every Lisp object, though, has at least -one C primitive for creating it. - - Recall from section (VII) that a Lisp object, as stored in a 32-bit -or 64-bit word, has a few tag bits, and a "value" that occupies the -remainder of the bits. We can separate the different Lisp object types -into three broad categories: - - * (a) Those for whom the value directly represents the contents of - the Lisp object. Only two types are in this category: integers and - characters. No special allocation or garbage collection is - necessary for such objects. Lisp objects of these types do not - need to be `GCPRO'ed. - - In the remaining two categories, the type is stored in the object -itself. The tag for all such objects is the generic "lrecord" -(Lisp_Type_Record) tag. The first bytes of the object's structure are -an integer (actually a char) characterising the object's type and some -flags, in particular the mark bit used for garbage collection. A -structure describing the type is accessible thru the -lrecord_implementation_table indexed with said integer. This structure -includes the method pointers and a pointer to a string naming the type. - - * (b) Those lrecords that are allocated in frob blocks (see above). - This includes the objects that are most common and relatively - small, and includes conses, strings, subrs, floats, compiled - functions, symbols, extents, events, and markers. With the - cleanup of frob blocks done in 19.12, it's not terribly hard to - add more objects to this category, but it's a bit trickier than - adding an object type to type (c) (esp. if the object needs a - finalization method), and is not likely to save much space unless - the object is small and there are many of them. (In fact, if there - are very few of them, it might actually waste space.) - - * (c) Those lrecords that are individually `malloc()'ed. These are - called "lcrecords". All other types are in this category. Adding - a new type to this category is comparatively easy, and all types - added since 19.8 (when the current allocation scheme was devised, - by Richard Mlynarik), with the exception of the character type, - have been in this category. - - Note that bit vectors are a bit of a special case. They are simple -lrecords as in category (b), but are individually `malloc()'ed like -vectors. You can basically view them as exactly like vectors except -that their type is stored in lrecord fashion rather than in -directly-tagged fashion. - - -File: internals.info, Node: Garbage Collection, Next: GCPROing, Prev: Introduction to Allocation, Up: Allocation of Objects in XEmacs Lisp - -Garbage Collection -================== - - Garbage collection is simple in theory but tricky to implement. -Emacs Lisp uses the oldest garbage collection method, called "mark and -sweep". Garbage collection begins by starting with all accessible -locations (i.e. all variables and other slots where Lisp objects might -occur) and recursively traversing all objects accessible from those -slots, marking each one that is found. We then go through all of -memory and free each object that is not marked, and unmarking each -object that is marked. Note that "all of memory" means all currently -allocated objects. Traversing all these objects means traversing all -frob blocks, all vectors (which are chained in one big list), and all -lcrecords (which are likewise chained). - - Garbage collection can be invoked explicitly by calling -`garbage-collect' but is also called automatically by `eval', once a -certain amount of memory has been allocated since the last garbage -collection (according to `gc-cons-threshold'). - diff -u -r -N xemacs-21.4.14/info/internals.info-5 xemacs-21.4.15/info/internals.info-5 --- xemacs-21.4.14/info/internals.info-5 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-5 1969-12-31 19:00:00.000000000 -0500 @@ -1,940 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: GCPROing, Next: Garbage Collection - Step by Step, Prev: Garbage Collection, Up: Allocation of Objects in XEmacs Lisp - -`GCPRO'ing -========== - - `GCPRO'ing is one of the ugliest and trickiest parts of Emacs -internals. The basic idea is that whenever garbage collection occurs, -all in-use objects must be reachable somehow or other from one of the -roots of accessibility. The roots of accessibility are: - - 1. All objects that have been `staticpro()'d or - `staticpro_nodump()'ed. This is used for any global C variables - that hold Lisp objects. A call to `staticpro()' happens implicitly - as a result of any symbols declared with `defsymbol()' and any - variables declared with `DEFVAR_FOO()'. You need to explicitly - call `staticpro()' (in the `vars_of_foo()' method of a module) for - other global C variables holding Lisp objects. (This typically - includes internal lists and such things.). Use - `staticpro_nodump()' only in the rare cases when you do not want - the pointed variable to be saved at dump time but rather recompute - it at startup. - - Note that `obarray' is one of the `staticpro()'d things. - Therefore, all functions and variables get marked through this. - - 2. Any shadowed bindings that are sitting on the `specpdl' stack. - - 3. Any objects sitting in currently active (Lisp) stack frames, - catches, and condition cases. - - 4. A couple of special-case places where active objects are located. - - 5. Anything currently marked with `GCPRO'. - - Marking with `GCPRO' is necessary because some C functions (quite a -lot, in fact), allocate objects during their operation. Quite -frequently, there will be no other pointer to the object while the -function is running, and if a garbage collection occurs and the object -needs to be referenced again, bad things will happen. The solution is -to mark those objects with `GCPRO'. Unfortunately this is easy to -forget, and there is basically no way around this problem. Here are -some rules, though: - - 1. For every `GCPRON', there have to be declarations of `struct gcpro - gcpro1, gcpro2', etc. - - 2. You _must_ `UNGCPRO' anything that's `GCPRO'ed, and you _must not_ - `UNGCPRO' if you haven't `GCPRO'ed. Getting either of these wrong - will lead to crashes, often in completely random places unrelated - to where the problem lies. - - 3. The way this actually works is that all currently active `GCPRO's - are chained through the `struct gcpro' local variables, with the - variable `gcprolist' pointing to the head of the list and the nth - local `gcpro' variable pointing to the first `gcpro' variable in - the next enclosing stack frame. Each `GCPRO'ed thing is an - lvalue, and the `struct gcpro' local variable contains a pointer to - this lvalue. This is why things will mess up badly if you don't - pair up the `GCPRO's and `UNGCPRO's--you will end up with - `gcprolist's containing pointers to `struct gcpro's or local - `Lisp_Object' variables in no-longer-active stack frames. - - 4. It is actually possible for a single `struct gcpro' to protect a - contiguous array of any number of values, rather than just a - single lvalue. To effect this, call `GCPRON' as usual on the - first object in the array and then set `gcproN.nvars'. - - 5. *Strings are relocated.* What this means in practice is that the - pointer obtained using `XSTRING_DATA()' is liable to change at any - time, and you should never keep it around past any function call, - or pass it as an argument to any function that might cause a - garbage collection. This is why a number of functions accept - either a "non-relocatable" `char *' pointer or a relocatable Lisp - string, and only access the Lisp string's data at the very last - minute. In some cases, you may end up having to `alloca()' some - space and copy the string's data into it. - - 6. By convention, if you have to nest `GCPRO''s, use `NGCPRON' (along - with `struct gcpro ngcpro1, ngcpro2', etc.), `NNGCPRON', etc. - This avoids compiler warnings about shadowed locals. - - 7. It is _always_ better to err on the side of extra `GCPRO's rather - than too few. The extra cycles spent on this are almost never - going to make a whit of difference in the speed of anything. - - 8. The general rule to follow is that caller, not callee, `GCPRO's. - That is, you should not have to explicitly `GCPRO' any Lisp objects - that are passed in as parameters. - - One exception from this rule is if you ever plan to change the - parameter value, and store a new object in it. In that case, you - _must_ `GCPRO' the parameter, because otherwise the new object - will not be protected. - - So, if you create any Lisp objects (remember, this happens in all - sorts of circumstances, e.g. with `Fcons()', etc.), you are - responsible for `GCPRO'ing them, unless you are _absolutely sure_ - that there's no possibility that a garbage-collection can occur - while you need to use the object. Even then, consider `GCPRO'ing. - - 9. A garbage collection can occur whenever anything calls `Feval', or - whenever a QUIT can occur where execution can continue past this. - (Remember, this is almost anywhere.) - - 10. If you have the _least smidgeon of doubt_ about whether you need - to `GCPRO', you should `GCPRO'. - - 11. Beware of `GCPRO'ing something that is uninitialized. If you have - any shade of doubt about this, initialize all your variables to - `Qnil'. - - 12. Be careful of traps, like calling `Fcons()' in the argument to - another function. By the "caller protects" law, you should be - `GCPRO'ing the newly-created cons, but you aren't. A certain - number of functions that are commonly called on freshly created - stuff (e.g. `nconc2()', `Fsignal()'), break the "caller protects" - law and go ahead and `GCPRO' their arguments so as to simplify - things, but make sure and check if it's OK whenever doing - something like this. - - 13. Once again, remember to `GCPRO'! Bugs resulting from insufficient - `GCPRO'ing are intermittent and extremely difficult to track down, - often showing up in crashes inside of `garbage-collect' or in - weirdly corrupted objects or even in incorrect values in a totally - different section of code. - - If you don't understand whether to `GCPRO' in a particular instance, -ask on the mailing lists. A general hint is that `prog1' is the -canonical example - - Given the extremely error-prone nature of the `GCPRO' scheme, and -the difficulties in tracking down, it should be considered a deficiency -in the XEmacs code. A solution to this problem would involve -implementing so-called "conservative" garbage collection for the C -stack. That involves looking through all of stack memory and treating -anything that looks like a reference to an object as a reference. This -will result in a few objects not getting collected when they should, but -it obviates the need for `GCPRO'ing, and allows garbage collection to -happen at any point at all, such as during object allocation. - - -File: internals.info, Node: Garbage Collection - Step by Step, Next: Integers and Characters, Prev: GCPROing, Up: Allocation of Objects in XEmacs Lisp - -Garbage Collection - Step by Step -================================= - -* Menu: - -* Invocation:: -* garbage_collect_1:: -* mark_object:: -* gc_sweep:: -* sweep_lcrecords_1:: -* compact_string_chars:: -* sweep_strings:: -* sweep_bit_vectors_1:: - - -File: internals.info, Node: Invocation, Next: garbage_collect_1, Up: Garbage Collection - Step by Step - -Invocation ----------- - - The first thing that anyone should know about garbage collection is: -when and how the garbage collector is invoked. One might think that this -could happen every time new memory is allocated, e.g. new objects are -created, but this is _not_ the case. Instead, we have the following -situation: - - The entry point of any process of garbage collection is an invocation -of the function `garbage_collect_1' in file `alloc.c'. The invocation -can occur _explicitly_ by calling the function `Fgarbage_collect' (in -addition this function provides information about the freed memory), or -can occur _implicitly_ in four different situations: - 1. In function `main_1' in file `emacs.c'. This function is called at - each startup of xemacs. The garbage collection is invoked after all - initial creations are completed, but only if a special internal - error checking-constant `ERROR_CHECK_GC' is defined. - - 2. In function `disksave_object_finalization' in file `alloc.c'. The - only purpose of this function is to clear the objects from memory - which need not be stored with xemacs when we dump out an - executable. This is only done by `Fdump_emacs' or by - `Fdump_emacs_data' respectively (both in `emacs.c'). The actual - clearing is accomplished by making these objects unreachable and - starting a garbage collection. The function is only used while - building xemacs. - - 3. In function `Feval / eval' in file `eval.c'. Each time the well - known and often used function eval is called to evaluate a form, - one of the first things that could happen, is a potential call of - `garbage_collect_1'. There exist three global variables, - `consing_since_gc' (counts the created cons-cells since the last - garbage collection), `gc_cons_threshold' (a specified threshold - after which a garbage collection occurs) and `always_gc'. If - `always_gc' is set or if the threshold is exceeded, the garbage - collection will start. - - 4. In function `Ffuncall / funcall' in file `eval.c'. This function - evaluates calls of elisp functions and works according to `Feval'. - - The upshot is that garbage collection can basically occur everywhere -`Feval', respectively `Ffuncall', is used - either directly or through -another function. Since calls to these two functions are hidden in -various other functions, many calls to `garbage_collect_1' are not -obviously foreseeable, and therefore unexpected. Instances where they -are used that are worth remembering are various elisp commands, as for -example `or', `and', `if', `cond', `while', `setq', etc., miscellaneous -`gui_item_...' functions, everything related to `eval' (`Feval_buffer', -`call0', ...) and inside `Fsignal'. The latter is used to handle -signals, as for example the ones raised by every `QUIT'-macro triggered -after pressing Ctrl-g. - - -File: internals.info, Node: garbage_collect_1, Next: mark_object, Prev: Invocation, Up: Garbage Collection - Step by Step - -`garbage_collect_1' -------------------- - - We can now describe exactly what happens after the invocation takes -place. - 1. There are several cases in which the garbage collector is left - immediately: when we are already garbage collecting - (`gc_in_progress'), when the garbage collection is somehow - forbidden (`gc_currently_forbidden'), when we are currently - displaying something (`in_display') or when we are preparing for - the armageddon of the whole system (`preparing_for_armageddon'). - - 2. Next the correct frame in which to put all the output occurring - during garbage collecting is determined. In order to be able to - restore the old display's state after displaying the message, some - data about the current cursor position has to be saved. The - variables `pre_gc_cursor' and `cursor_changed' take care of that. - - 3. The state of `gc_currently_forbidden' must be restored after the - garbage collection, no matter what happens during the process. We - accomplish this by `record_unwind_protect'ing the suitable function - `restore_gc_inhibit' together with the current value of - `gc_currently_forbidden'. - - 4. If we are concurrently running an interactive xemacs session, the - next step is simply to show the garbage collector's cursor/message. - - 5. The following steps are the intrinsic steps of the garbage - collector, therefore `gc_in_progress' is set. - - 6. For debugging purposes, it is possible to copy the current C stack - frame. However, this seems to be a currently unused feature. - - 7. Before actually starting to go over all live objects, references to - objects that are no longer used are pruned. We only have to do - this for events (`clear_event_resource') and for specifiers - (`cleanup_specifiers'). - - 8. Now the mark phase begins and marks all accessible elements. In - order to start from all slots that serve as roots of - accessibility, the function `mark_object' is called for each root - individually to go out from there to mark all reachable objects. - All roots that are traversed are shown in their processed order: - * all constant symbols and static variables that are registered - via `staticpro' in the dynarr `staticpros'. *Note Adding - Global Lisp Variables::. - - * all Lisp objects that are created in C functions and that - must be protected from freeing them. They are registered in - the global list `gcprolist'. *Note GCPROing::. - - * all local variables (i.e. their name fields `symbol' and old - values `old_values') that are bound during the evaluation by - the Lisp engine. They are stored in `specbinding' structs - pushed on a stack called `specpdl'. *Note Dynamic Binding; - The specbinding Stack; Unwind-Protects::. - - * all catch blocks that the Lisp engine encounters during the - evaluation cause the creation of structs `catchtag' inserted - in the list `catchlist'. Their tag (`tag') and value (`val' - fields are freshly created objects and therefore have to be - marked. *Note Catch and Throw::. - - * every function application pushes new structs `backtrace' on - the call stack of the Lisp engine (`backtrace_list'). The - unique parts that have to be marked are the fields for each - function (`function') and all their arguments (`args'). - *Note Evaluation::. - - * all objects that are used by the redisplay engine that must - not be freed are marked by a special function called - `mark_redisplay' (in `redisplay.c'). - - * all objects created for profiling purposes are allocated by C - functions instead of using the lisp allocation mechanisms. In - order to receive the right ones during the sweep phase, they - also have to be marked manually. That is done by the function - `mark_profiling_info' - - 9. Hash tables in XEmacs belong to a kind of special objects that - make use of a concept often called 'weak pointers'. To make a - long story short, these kind of pointers are not followed during - the estimation of the live objects during garbage collection. Any - object referenced only by weak pointers is collected anyway, and - the reference to it is cleared. In hash tables there are different - usage patterns of them, manifesting in different types of hash - tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak' - (internally also 'key-car-weak' and 'value-car-weak') hash tables, - each clearing entries depending on different conditions. More - information can be found in the documentation to the function - `make-hash-table'. - - Because there are complicated dependency rules about when and what - to mark while processing weak hash tables, the standard `marker' - method is only active if it is marking non-weak hash tables. As - soon as a weak component is in the table, the hash table entries - are ignored while marking. Instead their marking is done each - separately by the function `finish_marking_weak_hash_tables'. This - function iterates over each hash table entry `hentries' for each - weak hash table in `Vall_weak_hash_tables'. Depending on the type - of a table, the appropriate action is performed. If a table is - acting as `HASH_TABLE_KEY_WEAK', and a key already marked, - everything reachable from the `value' component is marked. If it is - acting as a `HASH_TABLE_VALUE_WEAK' and the value component is - already marked, the marking starts beginning only from the `key' - component. If it is a `HASH_TABLE_KEY_CAR_WEAK' and the car of - the key entry is already marked, we mark both the `key' and - `value' components. Finally, if the table is of the type - `HASH_TABLE_VALUE_CAR_WEAK' and the car of the value components is - already marked, again both the `key' and the `value' components - get marked. - - Again, there are lists with comparable properties called weak - lists. There exist different peculiarities of their types called - `simple', `assoc', `key-assoc' and `value-assoc'. You can find - further details about them in the description to the function - `make-weak-list'. The scheme of their marking is similar: all weak - lists are listed in `Qall_weak_lists', therefore we iterate over - them. The marking is advanced until we hit an already marked pair. - Then we know that during a former run all the rest has been marked - completely. Again, depending on the special type of the weak list, - our jobs differ. If it is a `WEAK_LIST_SIMPLE' and the elem is - marked, we mark the `cons' part. If it is a `WEAK_LIST_ASSOC' and - not a pair or a pair with both marked car and cdr, we mark the - `cons' and the `elem'. If it is a `WEAK_LIST_KEY_ASSOC' and not a - pair or a pair with a marked car of the elem, we mark the `cons' - and the `elem'. Finally, if it is a `WEAK_LIST_VALUE_ASSOC' and - not a pair or a pair with a marked cdr of the elem, we mark both - the `cons' and the `elem'. - - Since, by marking objects in reach from weak hash tables and weak - lists, other objects could get marked, this perhaps implies - further marking of other weak objects, both finishing functions - are redone as long as yet unmarked objects get freshly marked. - - 10. After completing the special marking for the weak hash tables and - for the weak lists, all entries that point to objects that are - going to be swept in the further process are useless, and - therefore have to be removed from the table or the list. - - The function `prune_weak_hash_tables' does the job for weak hash - tables. Totally unmarked hash tables are removed from the list - `Vall_weak_hash_tables'. The other ones are treated more carefully - by scanning over all entries and removing one as soon as one of - the components `key' and `value' is unmarked. - - The same idea applies to the weak lists. It is accomplished by - `prune_weak_lists': An unmarked list is pruned from - `Vall_weak_lists' immediately. A marked list is treated more - carefully by going over it and removing just the unmarked pairs. - - 11. The function `prune_specifiers' checks all listed specifiers held - in `Vall_specifiers' and removes the ones from the lists that are - unmarked. - - 12. All syntax tables are stored in a list called - `Vall_syntax_tables'. The function `prune_syntax_tables' walks - through it and unlinks the tables that are unmarked. - - 13. Next, we will attack the complete sweeping - the function - `gc_sweep' which holds the predominance. - - 14. First, all the variables with respect to garbage collection are - reset. `consing_since_gc' - the counter of the created cells since - the last garbage collection - is set back to 0, and - `gc_in_progress' is not `true' anymore. - - 15. In case the session is interactive, the displayed cursor and - message are removed again. - - 16. The state of `gc_inhibit' is restored to the former value by - unwinding the stack. - - 17. A small memory reserve is always held back that can be reached by - `breathing_space'. If nothing more is left, we create a new reserve - and exit. - - -File: internals.info, Node: mark_object, Next: gc_sweep, Prev: garbage_collect_1, Up: Garbage Collection - Step by Step - -`mark_object' -------------- - - The first thing that is checked while marking an object is whether -the object is a real Lisp object `Lisp_Type_Record' or just an integer -or a character. Integers and characters are the only two types that are -stored directly - without another level of indirection, and therefore -they don't have to be marked and collected. *Note How Lisp Objects Are -Represented in C::. - - The second case is the one we have to handle. It is the one when we -are dealing with a pointer to a Lisp object. But, there exist also three -possibilities, that prevent us from doing anything while marking: The -object is read only which prevents it from being garbage collected, -i.e. marked (`C_READONLY_RECORD_HEADER'). The object in question is -already marked, and need not be marked for the second time (checked by -`MARKED_RECORD_HEADER_P'). If it is a special, unmarkable object -(`UNMARKABLE_RECORD_HEADER_P', apparently, these are objects that sit -in some const space, and can therefore not be marked, see -`this_one_is_unmarkable' in `alloc.c'). - - Now, the actual marking is feasible. We do so by once using the macro -`MARK_RECORD_HEADER' to mark the object itself (actually the special -flag in the lrecord header), and calling its special marker "method" -`marker' if available. The marker method marks every other object that -is in reach from our current object. Note, that these marker methods -should not call `mark_object' recursively, but instead should return -the next object from where further marking has to be performed. - - In case another object was returned, as mentioned before, we -reiterate the whole `mark_object' process beginning with this next -object. - - -File: internals.info, Node: gc_sweep, Next: sweep_lcrecords_1, Prev: mark_object, Up: Garbage Collection - Step by Step - -`gc_sweep' ----------- - - The job of this function is to free all unmarked records from -memory. As we know, there are different types of objects implemented -and managed, and consequently different ways to free them from memory. -*Note Introduction to Allocation::. - - We start with all objects stored through `lcrecords'. All bulkier -objects are allocated and handled using that scheme of `lcrecords'. -Each object is `malloc'ed separately instead of placing it in one of -the contiguous frob blocks. All types that are currently stored using -`lcrecords''s `alloc_lcrecord' and `make_lcrecord_list' are the types: -vectors, buffers, char-table, char-table-entry, console, weak-list, -database, device, ldap, hash-table, command-builder, extent-auxiliary, -extent-info, face, coding-system, frame, image-instance, glyph, -popup-data, gui-item, keymap, charset, color_instance, font_instance, -opaque, opaque-list, process, range-table, specifier, -symbol-value-buffer-local, symbol-value-lisp-magic, -symbol-value-varalias, toolbar-button, tooltalk-message, -tooltalk-pattern, window, and window-configuration. We take care of -them in the fist place in order to be able to handle and to finalize -items stored in them more easily. The function `sweep_lcrecords_1' as -described below is doing the whole job for us. For a description about -the internals: *Note lrecords::. - - Our next candidates are the other objects that behave quite -differently than everything else: the strings. They consists of two -parts, a fixed-size portion (`struct Lisp_String') holding the string's -length, its property list and a pointer to the second part, and the -actual string data, which is stored in string-chars blocks comparable to -frob blocks. In this block, the data is not only freed, but also a -compression of holes is made, i.e. all strings are relocated together. -*Note String::. This compacting phase is performed by the function -`compact_string_chars', the actual sweeping by the function -`sweep_strings' is described below. - - After that, the other types are swept step by step using functions -`sweep_conses', `sweep_bit_vectors_1', `sweep_compiled_functions', -`sweep_floats', `sweep_symbols', `sweep_extents', `sweep_markers' and -`sweep_extents'. They are the fixed-size types cons, floats, -compiled-functions, symbol, marker, extent, and event stored in -so-called "frob blocks", and therefore we can basically do the same on -every type objects, using the same macros, especially defined only to -handle everything with respect to fixed-size blocks. The only fixed-size -type that is not handled here are the fixed-size portion of strings, -because we took special care of them earlier. - - The only big exceptions are bit vectors stored differently and -therefore treated differently by the function `sweep_bit_vectors_1' -described later. - - At first, we need some brief information about how these fixed-size -types are managed in general, in order to understand how the sweeping -is done. They have all a fixed size, and are therefore stored in big -blocks of memory - allocated at once - that can hold a certain amount -of objects of one type. The macro `DECLARE_FIXED_TYPE_ALLOC' creates -the suitable structures for every type. More precisely, we have the -block struct (holding a pointer to the previous block `prev' and the -objects in `block[]'), a pointer to current block -(`current_..._block)') and its last index (`current_..._block_index'), -and a pointer to the free list that will be created. Also a macro -`FIXED_TYPE_FROM_BLOCK' plus some related macros exists that are used -to obtain a new object, either from the free list -`ALLOCATE_FIXED_TYPE_1' if there is an unused object of that type -stored or by allocating a completely new block using -`ALLOCATE_FIXED_TYPE_FROM_BLOCK'. - - The rest works as follows: all of them define a macro `UNMARK_...' -that is used to unmark the object. They define a macro -`ADDITIONAL_FREE_...' that defines additional work that has to be done -when converting an object from in use to not in use (so far, only -markers use it in order to unchain them). Then, they all call the macro -`SWEEP_FIXED_TYPE_BLOCK' instantiated with their type name and their -struct name. - - This call in particular does the following: we go over all blocks -starting with the current moving towards the oldest. For each block, -we look at every object in it. If the object already freed (checked -with `FREE_STRUCT_P' using the first pointer of the object), or if it is -set to read only (`C_READONLY_RECORD_HEADER_P', nothing must be done. -If it is unmarked (checked with `MARKED_RECORD_HEADER_P'), it is put in -the free list and set free (using the macro `FREE_FIXED_TYPE', -otherwise it stays in the block, but is unmarked (by `UNMARK_...'). -While going through one block, we note if the whole block is empty. If -so, the whole block is freed (using `xfree') and the free list state is -set to the state it had before handling this block. - - -File: internals.info, Node: sweep_lcrecords_1, Next: compact_string_chars, Prev: gc_sweep, Up: Garbage Collection - Step by Step - -`sweep_lcrecords_1' -------------------- - - After nullifying the complete lcrecord statistics, we go over all -lcrecords two separate times. They are all chained together in a list -with a head called `all_lcrecords'. - - The first loop calls for each object its `finalizer' method, but only -in the case that it is not read only (`C_READONLY_RECORD_HEADER_P)', it -is not already marked (`MARKED_RECORD_HEADER_P'), it is not already in -a free list (list of freed objects, field `free') and finally it owns a -finalizer method. - - The second loop actually frees the appropriate objects again by -iterating through the whole list. In case an object is read only or -marked, it has to persist, otherwise it is manually freed by calling -`xfree'. During this loop, the lcrecord statistics are kept up to date -by calling `tick_lcrecord_stats' with the right arguments, - - -File: internals.info, Node: compact_string_chars, Next: sweep_strings, Prev: sweep_lcrecords_1, Up: Garbage Collection - Step by Step - -`compact_string_chars' ----------------------- - - The purpose of this function is to compact all the data parts of the -strings that are held in so-called `string_chars_block', i.e. the -strings that do not exceed a certain maximal length. - - The procedure with which this is done is as follows. We are keeping -two positions in the `string_chars_block's using two pointer/integer -pairs, namely `from_sb'/`from_pos' and `to_sb'/`to_pos'. They stand for -the actual positions, from where to where, to copy the actually handled -string. - - While going over all chained `string_char_block's and their held -strings, staring at `first_string_chars_block', both pointers are -advanced and eventually a string is copied from `from_sb' to `to_sb', -depending on the status of the pointed at strings. - - More precisely, we can distinguish between the following actions. - * The string at `from_sb''s position could be marked as free, which - is indicated by an invalid pointer to the pointer that should - point back to the fixed size string object, and which is checked by - `FREE_STRUCT_P'. In this case, the `from_sb'/`from_pos' is - advanced to the next string, and nothing has to be copied. - - * Also, if a string object itself is unmarked, nothing has to be - copied. We likewise advance the `from_sb'/`from_pos' pair as - described above. - - * In all other cases, we have a marked string at hand. The string - data must be moved from the from-position to the to-position. In - case there is not enough space in the actual `to_sb'-block, we - advance this pointer to the beginning of the next block before - copying. In case the from and to positions are different, we - perform the actual copying using the library function `memmove'. - - After compacting, the pointer to the current `string_chars_block', -sitting in `current_string_chars_block', is reset on the last block to -which we moved a string, i.e. `to_block', and all remaining blocks (we -know that they just carry garbage) are explicitly `xfree'd. - - -File: internals.info, Node: sweep_strings, Next: sweep_bit_vectors_1, Prev: compact_string_chars, Up: Garbage Collection - Step by Step - -`sweep_strings' ---------------- - - The sweeping for the fixed sized string objects is essentially -exactly the same as it is for all other fixed size types. As before, -the freeing into the suitable free list is done by using the macro -`SWEEP_FIXED_SIZE_BLOCK' after defining the right macros -`UNMARK_string' and `ADDITIONAL_FREE_string'. These two definitions are -a little bit special compared to the ones used for the other fixed size -types. - - `UNMARK_string' is defined the same way except some additional code -used for updating the bookkeeping information. - - For strings, `ADDITIONAL_FREE_string' has to do something in -addition: in case, the string was not allocated in a -`string_chars_block' because it exceeded the maximal length, and -therefore it was `malloc'ed separately, we know also `xfree' it -explicitly. - - -File: internals.info, Node: sweep_bit_vectors_1, Prev: sweep_strings, Up: Garbage Collection - Step by Step - -`sweep_bit_vectors_1' ---------------------- - - Bit vectors are also one of the rare types that are `malloc'ed -individually. Consequently, while sweeping, all further needless bit -vectors must be freed by hand. This is done, as one might imagine, the -expected way: since they are all registered in a list called -`all_bit_vectors', all elements of that list are traversed, all -unmarked bit vectors are unlinked by calling `xfree' and all of them -become unmarked. In addition, the bookkeeping information used for -garbage collector's output purposes is updated. - - -File: internals.info, Node: Integers and Characters, Next: Allocation from Frob Blocks, Prev: Garbage Collection - Step by Step, Up: Allocation of Objects in XEmacs Lisp - -Integers and Characters -======================= - - Integer and character Lisp objects are created from integers using -the macros `XSETINT()' and `XSETCHAR()' or the equivalent functions -`make_int()' and `make_char()'. (These are actually macros on most -systems.) These functions basically just do some moving of bits -around, since the integral value of the object is stored directly in -the `Lisp_Object'. - - `XSETINT()' and the like will truncate values given to them that are -too big; i.e. you won't get the value you expected but the tag bits -will at least be correct. - - -File: internals.info, Node: Allocation from Frob Blocks, Next: lrecords, Prev: Integers and Characters, Up: Allocation of Objects in XEmacs Lisp - -Allocation from Frob Blocks -=========================== - - The uninitialized memory required by a `Lisp_Object' of a particular -type is allocated using `ALLOCATE_FIXED_TYPE()'. This only occurs -inside of the lowest-level object-creating functions in `alloc.c': -`Fcons()', `make_float()', `Fmake_byte_code()', `Fmake_symbol()', -`allocate_extent()', `allocate_event()', `Fmake_marker()', and -`make_uninit_string()'. The idea is that, for each type, there are a -number of frob blocks (each 2K in size); each frob block is divided up -into object-sized chunks. Each frob block will have some of these -chunks that are currently assigned to objects, and perhaps some that are -free. (If a frob block has nothing but free chunks, it is freed at the -end of the garbage collection cycle.) The free chunks are stored in a -free list, which is chained by storing a pointer in the first four bytes -of the chunk. (Except for the free chunks at the end of the last frob -block, which are handled using an index which points past the end of the -last-allocated chunk in the last frob block.) `ALLOCATE_FIXED_TYPE()' -first tries to retrieve a chunk from the free list; if that fails, it -calls `ALLOCATE_FIXED_TYPE_FROM_BLOCK()', which looks at the end of the -last frob block for space, and creates a new frob block if there is -none. (There are actually two versions of these macros, one of which is -more defensive but less efficient and is used for error-checking.) - - -File: internals.info, Node: lrecords, Next: Low-level allocation, Prev: Allocation from Frob Blocks, Up: Allocation of Objects in XEmacs Lisp - -lrecords -======== - - [see `lrecord.h'] - - All lrecords have at the beginning of their structure a `struct -lrecord_header'. This just contains a type number and some flags, -including the mark bit. All builtin type numbers are defined as -constants in `enum lrecord_type', to allow the compiler to generate -more efficient code for `TYPEP'. The type number, thru the -`lrecord_implementation_table', gives access to a `struct -lrecord_implementation', which is a structure containing method pointers -and such. There is one of these for each type, and it is a global, -constant, statically-declared structure that is declared in the -`DEFINE_LRECORD_IMPLEMENTATION()' macro. - - Simple lrecords (of type (b) above) just have a `struct -lrecord_header' at their beginning. lcrecords, however, actually have a -`struct lcrecord_header'. This, in turn, has a `struct lrecord_header' -at its beginning, so sanity is preserved; but it also has a pointer -used to chain all lcrecords together, and a special ID field used to -distinguish one lcrecord from another. (This field is used only for -debugging and could be removed, but the space gain is not significant.) - - Simple lrecords are created using `ALLOCATE_FIXED_TYPE()', just like -for other frob blocks. The only change is that the implementation -pointer must be initialized correctly. (The implementation structure for -an lrecord, or rather the pointer to it, is named `lrecord_float', -`lrecord_extent', `lrecord_buffer', etc.) - - lcrecords are created using `alloc_lcrecord()'. This takes a size -to allocate and an implementation pointer. (The size needs to be passed -because some lcrecords, such as window configurations, are of variable -size.) This basically just `malloc()'s the storage, initializes the -`struct lcrecord_header', and chains the lcrecord onto the head of the -list of all lcrecords, which is stored in the variable `all_lcrecords'. -The calls to `alloc_lcrecord()' generally occur in the lowest-level -allocation function for each lrecord type. - - Whenever you create an lrecord, you need to call either -`DEFINE_LRECORD_IMPLEMENTATION()' or -`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()'. This needs to be specified -in a `.c' file, at the top level. What this actually does is define -and initialize the implementation structure for the lrecord. (And -possibly declares a function `error_check_foo()' that implements the -`XFOO()' macro when error-checking is enabled.) The arguments to the -macros are the actual type name (this is used to construct the C -variable name of the lrecord implementation structure and related -structures using the `##' macro concatenation operator), a string that -names the type on the Lisp level (this may not be the same as the C -type name; typically, the C type name has underscores, while the Lisp -string has dashes), various method pointers, and the name of the C -structure that contains the object. The methods are used to -encapsulate type-specific information about the object, such as how to -print it or mark it for garbage collection, so that it's easy to add -new object types without having to add a specific case for each new -type in a bunch of different places. - - The difference between `DEFINE_LRECORD_IMPLEMENTATION()' and -`DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION()' is that the former is used -for fixed-size object types and the latter is for variable-size object -types. Most object types are fixed-size; some complex types, however -(e.g. window configurations), are variable-size. Variable-size object -types have an extra method, which is called to determine the actual -size of a particular object of that type. (Currently this is only used -for keeping allocation statistics.) - - For the purpose of keeping allocation statistics, the allocation -engine keeps a list of all the different types that exist. Note that, -since `DEFINE_LRECORD_IMPLEMENTATION()' is a macro that is specified at -top-level, there is no way for it to initialize the global data -structures containing type information, like -`lrecord_implementations_table'. For this reason a call to -`INIT_LRECORD_IMPLEMENTATION' must be added to the same source file -containing `DEFINE_LRECORD_IMPLEMENTATION', but instead of to the top -level, to one of the init functions, typically `syms_of_FOO.c'. -`INIT_LRECORD_IMPLEMENTATION' must be called before an object of this -type is used. - - The type number is also used to index into an array holding the -number of objects of each type and the total memory allocated for -objects of that type. The statistics in this array are computed during -the sweep stage. These statistics are returned by the call to -`garbage-collect'. - - Note that for every type defined with a `DEFINE_LRECORD_*()' macro, -there needs to be a `DECLARE_LRECORD_IMPLEMENTATION()' somewhere in a -`.h' file, and this `.h' file needs to be included by `inline.c'. - - Furthermore, there should generally be a set of `XFOOBAR()', -`FOOBARP()', etc. macros in a `.h' (or occasionally `.c') file. To -create one of these, copy an existing model and modify as necessary. - - *Please note:* If you define an lrecord in an external -dynamically-loaded module, you must use `DECLARE_EXTERNAL_LRECORD', -`DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION', and -`DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION' instead of the -non-EXTERNAL forms. These macros will dynamically add new type numbers -to the global enum that records them, whereas the non-EXTERNAL forms -assume that the programmer has already inserted the correct type numbers -into the enum's code at compile-time. - - The various methods in the lrecord implementation structure are: - - 1. A "mark" method. This is called during the marking stage and - passed a function pointer (usually the `mark_object()' function), - which is used to mark an object. All Lisp objects that are - contained within the object need to be marked by applying this - function to them. The mark method should also return a Lisp - object, which should be either `nil' or an object to mark. (This - can be used in lieu of calling `mark_object()' on the object, to - reduce the recursion depth, and consequently should be the most - heavily nested sub-object, such as a long list.) - - *Please note:* When the mark method is called, garbage collection - is in progress, and special precautions need to be taken when - accessing objects; see section (B) above. - - If your mark method does not need to do anything, it can be `NULL'. - - 2. A "print" method. This is called to create a printed - representation of the object, whenever `princ', `prin1', or the - like is called. It is passed the object, a stream to which the - output is to be directed, and an `escapeflag' which indicates - whether the object's printed representation should be "escaped" so - that it is readable. (This corresponds to the difference between - `princ' and `prin1'.) Basically, "escaped" means that strings will - have quotes around them and confusing characters in the strings - such as quotes, backslashes, and newlines will be backslashed; and - that special care will be taken to make symbols print in a - readable fashion (e.g. symbols that look like numbers will be - backslashed). Other readable objects should perhaps pass - `escapeflag' on when sub-objects are printed, so that readability - is preserved when necessary (or if not, always pass in a 1 for - `escapeflag'). Non-readable objects should in general ignore - `escapeflag', except that some use it as an indication that more - verbose output should be given. - - Sub-objects are printed using `print_internal()', which takes - exactly the same arguments as are passed to the print method. - - Literal C strings should be printed using `write_c_string()', or - `write_string_1()' for non-null-terminated strings. - - Functions that do not have a readable representation should check - the `print_readably' flag and signal an error if it is set. - - If you specify NULL for the print method, the - `default_object_printer()' will be used. - - 3. A "finalize" method. This is called at the beginning of the sweep - stage on lcrecords that are about to be freed, and should be used - to perform any extra object cleanup. This typically involves - freeing any extra `malloc()'ed memory associated with the object, - releasing any operating-system and window-system resources - associated with the object (e.g. pixmaps, fonts), etc. - - The finalize method can be NULL if nothing needs to be done. - - WARNING #1: The finalize method is also called at the end of the - dump phase; this time with the for_disksave parameter set to - non-zero. The object is _not_ about to disappear, so you have to - make sure to _not_ free any extra `malloc()'ed memory if you're - going to need it later. (Also, signal an error if there are any - operating-system and window-system resources here, because they - can't be dumped.) - - Finalize methods should, as a rule, set to zero any pointers after - they've been freed, and check to make sure pointers are not zero - before freeing. Although I'm pretty sure that finalize methods - are not called twice on the same object (except for the - `for_disksave' proviso), we've gotten nastily burned in some cases - by not doing this. - - WARNING #2: The finalize method is _only_ called for lcrecords, - _not_ for simply lrecords. If you need a finalize method for - simple lrecords, you have to stick it in the - `ADDITIONAL_FREE_foo()' macro in `alloc.c'. - - WARNING #3: Things are in an _extremely_ bizarre state when - `ADDITIONAL_FREE_foo()' is called, so you have to be incredibly - careful when writing one of these functions. See the comment in - `gc_sweep()'. If you ever have to add one of these, consider - using an lcrecord or dealing with the problem in a different - fashion. - - 4. An "equal" method. This compares the two objects for similarity, - when `equal' is called. It should compare the contents of the - objects in some reasonable fashion. It is passed the two objects - and a "depth" value, which is used to catch circular objects. To - compare sub-Lisp-objects, call `internal_equal()' and bump the - depth value by one. If this value gets too high, a - `circular-object' error will be signaled. - - If this is NULL, objects are `equal' only when they are `eq', i.e. - identical. - - 5. A "hash" method. This is used to hash objects when they are to be - compared with `equal'. The rule here is that if two objects are - `equal', they _must_ hash to the same value; i.e. your hash - function should use some subset of the sub-fields of the object - that are compared in the "equal" method. If you specify this - method as `NULL', the object's pointer will be used as the hash, - which will _fail_ if the object has an `equal' method, so don't do - this. - - To hash a sub-Lisp-object, call `internal_hash()'. Bump the depth - by one, just like in the "equal" method. - - To convert a Lisp object directly into a hash value (using its - pointer), use `LISP_HASH()'. This is what happens when the hash - method is NULL. - - To hash two or more values together into a single value, use - `HASH2()', `HASH3()', `HASH4()', etc. - - 6. "getprop", "putprop", "remprop", and "plist" methods. These are - used for object types that have properties. I don't feel like - documenting them here. If you create one of these objects, you - have to use different macros to define them, i.e. - `DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS()' or - `DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS()'. - - 7. A "size_in_bytes" method, when the object is of variable-size. - (i.e. declared with a `_SEQUENCE_IMPLEMENTATION' macro.) This - should simply return the object's size in bytes, exactly as you - might expect. For an example, see the methods for window - configurations and opaques. - diff -u -r -N xemacs-21.4.14/info/internals.info-6 xemacs-21.4.15/info/internals.info-6 --- xemacs-21.4.14/info/internals.info-6 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-6 1969-12-31 19:00:00.000000000 -0500 @@ -1,1050 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Low-level allocation, Next: Cons, Prev: lrecords, Up: Allocation of Objects in XEmacs Lisp - -Low-level allocation -==================== - - Memory that you want to allocate directly should be allocated using -`xmalloc()' rather than `malloc()'. This implements error-checking on -the return value, and once upon a time did some more vital stuff (i.e. -`BLOCK_INPUT', which is no longer necessary). Free using `xfree()', -and realloc using `xrealloc()'. Note that `xmalloc()' will do a -non-local exit if the memory can't be allocated. (Many functions, -however, do not expect this, and thus XEmacs will likely crash if this -happens. *This is a bug.* If you can, you should strive to make your -function handle this OK. However, it's difficult in the general -circumstance, perhaps requiring extra unwind-protects and such.) - - Note that XEmacs provides two separate replacements for the standard -`malloc()' library function. These are called "old GNU malloc" -(`malloc.c') and "new GNU malloc" (`gmalloc.c'), respectively. New GNU -malloc is better in pretty much every way than old GNU malloc, and -should be used if possible. (It used to be that on some systems, the -old one worked but the new one didn't. I think this was due -specifically to a bug in SunOS, which the new one now works around; so -I don't think the old one ever has to be used any more.) The primary -difference between both of these mallocs and the standard system malloc -is that they are much faster, at the expense of increased space. The -basic idea is that memory is allocated in fixed chunks of powers of -two. This allows for basically constant malloc time, since the various -chunks can just be kept on a number of free lists. (The standard system -malloc typically allocates arbitrary-sized chunks and has to spend some -time, sometimes a significant amount of time, walking the heap looking -for a free block to use and cleaning things up.) The new GNU malloc -improves on things by allocating large objects in chunks of 4096 bytes -rather than in ever larger powers of two, which results in ever larger -wastage. There is a slight speed loss here, but it's of doubtful -significance. - - NOTE: Apparently there is a third-generation GNU malloc that is -significantly better than the new GNU malloc, and should probably be -included in XEmacs. - - There is also the relocating allocator, `ralloc.c'. This actually -moves blocks of memory around so that the `sbrk()' pointer shrunk and -virtual memory released back to the system. On some systems, this is a -big win. On all systems, it causes a noticeable (and sometimes huge) -speed penalty, so I turn it off by default. `ralloc.c' only works with -the new GNU malloc in `gmalloc.c'. There are also two versions of -`ralloc.c', one that uses `mmap()' rather than block copies to move -data around. This purports to be faster, although that depends on the -amount of data that would have had to be block copied and the -system-call overhead for `mmap()'. I don't know exactly how this -works, except that the relocating-allocation routines are pretty much -used only for the memory allocated for a buffer, which is the biggest -consumer of space, esp. of space that may get freed later. - - Note that the GNU mallocs have some "memory warning" facilities. -XEmacs taps into them and issues a warning through the standard warning -system, when memory gets to 75%, 85%, and 95% full. (On some systems, -the memory warnings are not functional.) - - Allocated memory that is going to be used to make a Lisp object is -created using `allocate_lisp_storage()'. This just calls `xmalloc()'. -It used to verify that the pointer to the memory can fit into a Lisp -word, before the current Lisp object representation was introduced. -`allocate_lisp_storage()' is called by `alloc_lcrecord()', -`ALLOCATE_FIXED_TYPE()', and the vector and bit-vector creation -routines. These routines also call `INCREMENT_CONS_COUNTER()' at the -appropriate times; this keeps statistics on how much memory is -allocated, so that garbage-collection can be invoked when the threshold -is reached. - - -File: internals.info, Node: Cons, Next: Vector, Prev: Low-level allocation, Up: Allocation of Objects in XEmacs Lisp - -Cons -==== - - Conses are allocated in standard frob blocks. The only thing to -note is that conses can be explicitly freed using `free_cons()' and -associated functions `free_list()' and `free_alist()'. This -immediately puts the conses onto the cons free list, and decrements the -statistics on memory allocation appropriately. This is used to good -effect by some extremely commonly-used code, to avoid generating extra -objects and thereby triggering GC sooner. However, you have to be -_extremely_ careful when doing this. If you mess this up, you will get -BADLY BURNED, and it has happened before. - - -File: internals.info, Node: Vector, Next: Bit Vector, Prev: Cons, Up: Allocation of Objects in XEmacs Lisp - -Vector -====== - - As mentioned above, each vector is `malloc()'ed individually, and -all are threaded through the variable `all_vectors'. Vectors are -marked strangely during garbage collection, by kludging the size field. -Note that the `struct Lisp_Vector' is declared with its `contents' -field being a _stretchy_ array of one element. It is actually -`malloc()'ed with the right size, however, and access to any element -through the `contents' array works fine. - - -File: internals.info, Node: Bit Vector, Next: Symbol, Prev: Vector, Up: Allocation of Objects in XEmacs Lisp - -Bit Vector -========== - - Bit vectors work exactly like vectors, except for more complicated -code to access an individual bit, and except for the fact that bit -vectors are lrecords while vectors are not. (The only difference here is -that there's an lrecord implementation pointer at the beginning and the -tag field in bit vector Lisp words is "lrecord" rather than "vector".) - - -File: internals.info, Node: Symbol, Next: Marker, Prev: Bit Vector, Up: Allocation of Objects in XEmacs Lisp - -Symbol -====== - - Symbols are also allocated in frob blocks. Symbols in the awful -horrible obarray structure are chained through their `next' field. - - Remember that `intern' looks up a symbol in an obarray, creating one -if necessary. - - -File: internals.info, Node: Marker, Next: String, Prev: Symbol, Up: Allocation of Objects in XEmacs Lisp - -Marker -====== - - Markers are allocated in frob blocks, as usual. They are kept in a -buffer unordered, but in a doubly-linked list so that they can easily -be removed. (Formerly this was a singly-linked list, but in some cases -garbage collection took an extraordinarily long time due to the O(N^2) -time required to remove lots of markers from a buffer.) Markers are -removed from a buffer in the finalize stage, in -`ADDITIONAL_FREE_marker()'. - - -File: internals.info, Node: String, Next: Compiled Function, Prev: Marker, Up: Allocation of Objects in XEmacs Lisp - -String -====== - - As mentioned above, strings are a special case. A string is -logically two parts, a fixed-size object (containing the length, -property list, and a pointer to the actual data), and the actual data -in the string. The fixed-size object is a `struct Lisp_String' and is -allocated in frob blocks, as usual. The actual data is stored in -special "string-chars blocks", which are 8K blocks of memory. -Currently-allocated strings are simply laid end to end in these -string-chars blocks, with a pointer back to the `struct Lisp_String' -stored before each string in the string-chars block. When a new string -needs to be allocated, the remaining space at the end of the last -string-chars block is used if there's enough, and a new string-chars -block is created otherwise. - - There are never any holes in the string-chars blocks due to the -string compaction and relocation that happens at the end of garbage -collection. During the sweep stage of garbage collection, when objects -are reclaimed, the garbage collector goes through all string-chars -blocks, looking for unused strings. Each chunk of string data is -preceded by a pointer to the corresponding `struct Lisp_String', which -indicates both whether the string is used and how big the string is, -i.e. how to get to the next chunk of string data. Holes are compressed -by block-copying the next string into the empty space and relocating the -pointer stored in the corresponding `struct Lisp_String'. *This means -you have to be careful with strings in your code.* See the section -above on `GCPRO'ing. - - Note that there is one situation not handled: a string that is too -big to fit into a string-chars block. Such strings, called "big -strings", are all `malloc()'ed as their own block. (#### Although it -would make more sense for the threshold for big strings to be somewhat -lower, e.g. 1/2 or 1/4 the size of a string-chars block. It seems that -this was indeed the case formerly--indeed, the threshold was set at -1/8--but Mly forgot about this when rewriting things for 19.8.) - - Note also that the string data in string-chars blocks is padded as -necessary so that proper alignment constraints on the `struct -Lisp_String' back pointers are maintained. - - Finally, strings can be resized. This happens in Mule when a -character is substituted with a different-length character, or during -modeline frobbing. (You could also export this to Lisp, but it's not -done so currently.) Resizing a string is a potentially tricky process. -If the change is small enough that the padding can absorb it, nothing -other than a simple memory move needs to be done. Keep in mind, -however, that the string can't shrink too much because the offset to the -next string in the string-chars block is computed by looking at the -length and rounding to the nearest multiple of four or eight. If the -string would shrink or expand beyond the correct padding, new string -data needs to be allocated at the end of the last string-chars block and -the data moved appropriately. This leaves some dead string data, which -is marked by putting a special marker of 0xFFFFFFFF in the `struct -Lisp_String' pointer before the data (there's no real `struct -Lisp_String' to point to and relocate), and storing the size of the dead -string data (which would normally be obtained from the now-non-existent -`struct Lisp_String') at the beginning of the dead string data gap. -The string compactor recognizes this special 0xFFFFFFFF marker and -handles it correctly. - - -File: internals.info, Node: Compiled Function, Prev: String, Up: Allocation of Objects in XEmacs Lisp - -Compiled Function -================= - - Not yet documented. - - -File: internals.info, Node: Dumping, Next: Events and the Event Loop, Prev: Allocation of Objects in XEmacs Lisp, Up: Top - -Dumping -******* - -What is dumping and its justification -===================================== - - The C code of XEmacs is just a Lisp engine with a lot of built-in -primitives useful for writing an editor. The editor itself is written -mostly in Lisp, and represents around 100K lines of code. Loading and -executing the initialization of all this code takes a bit a time (five -to ten times the usual startup time of current xemacs) and requires -having all the lisp source files around. Having to reload them each -time the editor is started would not be acceptable. - - The traditional solution to this problem is called dumping: the build -process first creates the lisp engine under the name `temacs', then -runs it until it has finished loading and initializing all the lisp -code, and eventually creates a new executable called `xemacs' including -both the object code in `temacs' and all the contents of the memory -after the initialization. - - This solution, while working, has a huge problem: the creation of the -new executable from the actual contents of memory is an extremely -system-specific process, quite error-prone, and which interferes with a -lot of system libraries (like malloc). It is even getting worse -nowadays with libraries using constructors which are automatically -called when the program is started (even before main()) which tend to -crash when they are called multiple times, once before dumping and once -after (IRIX 6.x libz.so pulls in some C++ image libraries thru -dependencies which have this problem). Writing the dumper is also one -of the most difficult parts of porting XEmacs to a new operating system. -Basically, `dumping' is an operation that is just not officially -supported on many operating systems. - - The aim of the portable dumper is to solve the same problem as the -system-specific dumper, that is to be able to reload quickly, using only -a small number of files, the fully initialized lisp part of the editor, -without any system-specific hacks. - -* Menu: - -* Overview:: -* Data descriptions:: -* Dumping phase:: -* Reloading phase:: -* Remaining issues:: - - -File: internals.info, Node: Overview, Next: Data descriptions, Up: Dumping - -Overview -======== - - The portable dumping system has to: - - 1. At dump time, write all initialized, non-quickly-rebuildable data - to a file [Note: currently named `xemacs.dmp', but the name will - change], along with all informations needed for the reloading. - - 2. When starting xemacs, reload the dump file, relocate it to its new - starting address if needed, and reinitialize all pointers to this - data. Also, rebuild all the quickly rebuildable data. - - -File: internals.info, Node: Data descriptions, Next: Dumping phase, Prev: Overview, Up: Dumping - -Data descriptions -================= - - The more complex task of the dumper is to be able to write lisp -objects (lrecords) and C structs to disk and reload them at a different -address, updating all the pointers they include in the process. This -is done by using external data descriptions that give information about -the layout of the structures in memory. - - The specification of these descriptions is in lrecord.h. A -description of an lrecord is an array of struct lrecord_description. -Each of these structs include a type, an offset in the structure and -some optional parameters depending on the type. For instance, here is -the string description: - - static const struct lrecord_description string_description[] = { - { XD_BYTECOUNT, offsetof (Lisp_String, size) }, - { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) }, - { XD_LISP_OBJECT, offsetof (Lisp_String, plist) }, - { XD_END } - }; - - The first line indicates a member of type Bytecount, which is used by -the next, indirect directive. The second means "there is a pointer to -some opaque data in the field `data'". The length of said data is -given by the expression `XD_INDIRECT(0, 1)', which means "the value in -the 0th line of the description (welcome to C) plus one". The third -line means "there is a Lisp_Object member `plist' in the Lisp_String -structure". `XD_END' then ends the description. - - This gives us all the information we need to move around what is -pointed to by a structure (C or lrecord) and, by transitivity, -everything that it points to. The only missing information for dumping -is the size of the structure. For lrecords, this is part of the -lrecord_implementation, so we don't need to duplicate it. For C -structures we use a struct struct_description, which includes a size -field and a pointer to an associated array of lrecord_description. - - -File: internals.info, Node: Dumping phase, Next: Reloading phase, Prev: Data descriptions, Up: Dumping - -Dumping phase -============= - - Dumping is done by calling the function pdump() (in dumper.c) which -is invoked from Fdump_emacs (in emacs.c). This function performs a -number of tasks. - -* Menu: - -* Object inventory:: -* Address allocation:: -* The header:: -* Data dumping:: -* Pointers dumping:: - - -File: internals.info, Node: Object inventory, Next: Address allocation, Up: Dumping phase - -Object inventory ----------------- - - The first task is to build the list of the objects to dump. This -includes: - - * lisp objects - - * C structures - - We end up with one `pdump_entry_list_elmt' per object group (arrays -of C structs are kept together) which includes a pointer to the first -object of the group, the per-object size and the count of objects in the -group, along with some other information which is initialized later. - - These entries are linked together in `pdump_entry_list' structures -and can be enumerated thru either: - - 1. the `pdump_object_table', an array of `pdump_entry_list', one per - lrecord type, indexed by type number. - - 2. the `pdump_opaque_data_list', used for the opaque data which does - not include pointers, and hence does not need descriptions. - - 3. the `pdump_struct_table', which is a vector of - `struct_description'/`pdump_entry_list' pairs, used for non-opaque - C structures. - - This uses a marking strategy similar to the garbage collector. Some -differences though: - - 1. We do not use the mark bit (which does not exist for C structures - anyway); we use a big hash table instead. - - 2. We do not use the mark function of lrecords but instead rely on the - external descriptions. This happens essentially because we need to - follow pointers to C structures and opaque data in addition to - Lisp_Object members. - - This is done by `pdump_register_object()', which handles Lisp_Object -variables, and `pdump_register_struct()' which handles C structures, -which both delegate the description management to -`pdump_register_sub()'. - - The hash table doubles as a map object to pdump_entry_list_elmt (i.e. -allows us to look up a pdump_entry_list_elmt with the object it points -to). Entries are added with `pdump_add_entry()' and looked up with -`pdump_get_entry()'. There is no need for entry removal. The hash -value is computed quite simply from the object pointer by -`pdump_make_hash()'. - - The roots for the marking are: - - 1. the `staticpro''ed variables (there is a special - `staticpro_nodump()' call for protected variables we do not want - to dump). - - 2. the variables registered via `dump_add_root_object' (`staticpro()' - is equivalent to `staticpro_nodump()' + `dump_add_root_object()'). - - 3. the variables registered via `dump_add_root_struct_ptr', each of - which points to a C structure. - - This does not include the GCPRO'ed variables, the specbinds, the -catchtags, the backlist, the redisplay or the profiling info, since we -do not want to rebuild the actual chain of lisp calls which end up to -the dump-emacs call, only the global variables. - - Weak lists and weak hash tables are dumped as if they were their -non-weak equivalent (without changing their type, of course). This has -not yet been a problem. - - -File: internals.info, Node: Address allocation, Next: The header, Prev: Object inventory, Up: Dumping phase - -Address allocation ------------------- - - The next step is to allocate the offsets of each of the objects in -the final dump file. This is done by `pdump_allocate_offset()' which -is called indirectly by `pdump_scan_by_alignment()'. - - The strategy to deal with alignment problems uses these facts: - - 1. real world alignment requirements are powers of two. - - 2. the C compiler is required to adjust the size of a struct so that - you can have an array of them next to each other. This means you - can have an upper bound of the alignment requirements of a given - structure by looking at which power of two its size is a multiple. - - 3. the non-variant part of variable size lrecords has an alignment - requirement of 4. - - Hence, for each lrecord type, C struct type or opaque data block the -alignment requirement is computed as a power of two, with a minimum of -2^2 for lrecords. `pdump_scan_by_alignment()' then scans all the -`pdump_entry_list_elmt''s, the ones with the highest requirements -first. This ensures the best packing. - - The maximum alignment requirement we take into account is 2^8. - - `pdump_allocate_offset()' only has to do a linear allocation, -starting at offset 256 (this leaves room for the header and keeps the -alignments happy). - - -File: internals.info, Node: The header, Next: Data dumping, Prev: Address allocation, Up: Dumping phase - -The header ----------- - - The next step creates the file and writes a header with a signature -and some random information in it. The `reloc_address' field, which -indicates at which address the file should be loaded if we want to avoid -post-reload relocation, is set to 0. It then seeks to offset 256 (base -offset for the objects). - - -File: internals.info, Node: Data dumping, Next: Pointers dumping, Prev: The header, Up: Dumping phase - -Data dumping ------------- - - The data is dumped in the same order as the addresses were allocated -by `pdump_dump_data()', called from `pdump_scan_by_alignment()'. This -function copies the data to a temporary buffer, relocates all pointers -in the object to the addresses allocated in step Address Allocation, -and writes it to the file. Using the same order means that, if we are -careful with lrecords whose size is not a multiple of 4, we are ensured -that the object is always written at the offset in the file allocated -in step Address Allocation. - - -File: internals.info, Node: Pointers dumping, Prev: Data dumping, Up: Dumping phase - -Pointers dumping ----------------- - - A bunch of tables needed to reassign properly the global pointers are -then written. They are: - - 1. the pdump_root_struct_ptrs dynarr - - 2. the pdump_opaques dynarr - - 3. a vector of all the offsets to the objects in the file that - include a description (for faster relocation at reload time) - - 4. the pdump_root_objects and pdump_weak_object_chains dynarrs. - - For each of the dynarrs we write both the pointer to the variables -and the relocated offset of the object they point to. Since these -variables are global, the pointers are still valid when restarting the -program and are used to regenerate the global pointers. - - The `pdump_weak_object_chains' dynarr is a special case. The -variables it points to are the head of weak linked lists of lisp objects -of the same type. Not all objects of this list are dumped so the -relocated pointer we associate with them points to the first dumped -object of the list, or Qnil if none is available. This is also the -reason why they are not used as roots for the purpose of object -enumeration. - - Some very important information like the `staticpros' and -`lrecord_implementations_table' are handled indirectly using -`dump_add_opaque' or `dump_add_root_struct_ptr'. - - This is the end of the dumping part. - - -File: internals.info, Node: Reloading phase, Next: Remaining issues, Prev: Dumping phase, Up: Dumping - -Reloading phase -=============== - -File loading ------------- - - The file is mmap'ed in memory (which ensures a PAGESIZE alignment, at -least 4096), or if mmap is unavailable or fails, a 256-bytes aligned -malloc is done and the file is loaded. - - Some variables are reinitialized from the values found in the header. - - The difference between the actual loading address and the -reloc_address is computed and will be used for all the relocations. - -Putting back the pdump_opaques ------------------------------- - - The memory contents are restored in the obvious and trivial way. - -Putting back the pdump_root_struct_ptrs ---------------------------------------- - - The variables pointed to by pdump_root_struct_ptrs in the dump phase -are reset to the right relocated object addresses. - -Object relocation ------------------ - - All the objects are relocated using their description and their -offset by `pdump_reloc_one'. This step is unnecessary if the -reloc_address is equal to the file loading address. - -Putting back the pdump_root_objects and pdump_weak_object_chains ----------------------------------------------------------------- - - Same as Putting back the pdump_root_struct_ptrs. - -Reorganize the hash tables --------------------------- - - Since some of the hash values in the lisp hash tables are -address-dependent, their layout is now wrong. So we go through each of -them and have them resorted by calling `pdump_reorganize_hash_table'. - - -File: internals.info, Node: Remaining issues, Prev: Reloading phase, Up: Dumping - -Remaining issues -================ - - The build process will have to start a post-dump xemacs, ask it the -loading address (which will, hopefully, be always the same between -different xemacs invocations) and relocate the file to the new address. -This way the object relocation phase will not have to be done, which -means no writes in the objects and that, because of the use of mmap, the -dumped data will be shared between all the xemacs running on the -computer. - - Some executable signature will be necessary to ensure that a given -dump file is really associated with a given executable, or random -crashes will occur. Maybe a random number set at compile or configure -time thru a define. This will also allow for having -differently-compiled xemacsen on the same system (mule and no-mule -comes to mind). - - The DOC file contents should probably end up in the dump file. - - -File: internals.info, Node: Events and the Event Loop, Next: Evaluation; Stack Frames; Bindings, Prev: Dumping, Up: Top - -Events and the Event Loop -************************* - -* Menu: - -* Introduction to Events:: -* Main Loop:: -* Specifics of the Event Gathering Mechanism:: -* Specifics About the Emacs Event:: -* The Event Stream Callback Routines:: -* Other Event Loop Functions:: -* Converting Events:: -* Dispatching Events; The Command Builder:: - - -File: internals.info, Node: Introduction to Events, Next: Main Loop, Up: Events and the Event Loop - -Introduction to Events -====================== - - An event is an object that encapsulates information about an -interesting occurrence in the operating system. Events are generated -either by user action, direct (e.g. typing on the keyboard or moving -the mouse) or indirect (moving another window, thereby generating an -expose event on an Emacs frame), or as a result of some other typically -asynchronous action happening, such as output from a subprocess being -ready or a timer expiring. Events come into the system in an -asynchronous fashion (typically through a callback being called) and -are converted into a synchronous event queue (first-in, first-out) in a -process that we will call "collection". - - Note that each application has its own event queue. (It is -immaterial whether the collection process directly puts the events in -the proper application's queue, or puts them into a single system -queue, which is later split up.) - - The most basic level of event collection is done by the operating -system or window system. Typically, XEmacs does its own event -collection as well. Often there are multiple layers of collection in -XEmacs, with events from various sources being collected into a queue, -which is then combined with other sources to go into another queue -(i.e. a second level of collection), with perhaps another level on top -of this, etc. - - XEmacs has its own types of events (called "Emacs events"), which -provides an abstract layer on top of the system-dependent nature of the -most basic events that are received. Part of the complex nature of the -XEmacs event collection process involves converting from the -operating-system events into the proper Emacs events--there may not be -a one-to-one correspondence. - - Emacs events are documented in `events.h'; I'll discuss them later. - - -File: internals.info, Node: Main Loop, Next: Specifics of the Event Gathering Mechanism, Prev: Introduction to Events, Up: Events and the Event Loop - -Main Loop -========= - - The "command loop" is the top-level loop that the editor is always -running. It loops endlessly, calling `next-event' to retrieve an event -and `dispatch-event' to execute it. `dispatch-event' does the -appropriate thing with non-user events (process, timeout, magic, eval, -mouse motion); this involves calling a Lisp handler function, redrawing -a newly-exposed part of a frame, reading subprocess output, etc. For -user events, `dispatch-event' looks up the event in relevant keymaps or -menubars; when a full key sequence or menubar selection is reached, the -appropriate function is executed. `dispatch-event' may have to keep -state across calls; this is done in the "command-builder" structure -associated with each console (remember, there's usually only one -console), and the engine that looks up keystrokes and constructs full -key sequences is called the "command builder". This is documented -elsewhere. - - The guts of the command loop are in `command_loop_1()'. This -function doesn't catch errors, though--that's the job of -`command_loop_2()', which is a condition-case (i.e. error-trapping) -wrapper around `command_loop_1()'. `command_loop_1()' never returns, -but may get thrown out of. - - When an error occurs, `cmd_error()' is called, which usually invokes -the Lisp error handler in `command-error'; however, a default error -handler is provided if `command-error' is `nil' (e.g. during startup). -The purpose of the error handler is simply to display the error message -and do associated cleanup; it does not need to throw anywhere. When -the error handler finishes, the condition-case in `command_loop_2()' -will finish and `command_loop_2()' will reinvoke `command_loop_1()'. - - `command_loop_2()' is invoked from three places: from -`initial_command_loop()' (called from `main()' at the end of internal -initialization), from the Lisp function `recursive-edit', and from -`call_command_loop()'. - - `call_command_loop()' is called when a macro is started and when the -minibuffer is entered; normal termination of the macro or minibuffer -causes a throw out of the recursive command loop. (To -`execute-kbd-macro' for macros and `exit' for minibuffers. Note also -that the low-level minibuffer-entering function, -`read-minibuffer-internal', provides its own error handling and does -not need `command_loop_2()''s error encapsulation; so it tells -`call_command_loop()' to invoke `command_loop_1()' directly.) - - Note that both read-minibuffer-internal and recursive-edit set up a -catch for `exit'; this is why `abort-recursive-edit', which throws to -this catch, exits out of either one. - - `initial_command_loop()', called from `main()', sets up a catch for -`top-level' when invoking `command_loop_2()', allowing functions to -throw all the way to the top level if they really need to. Before -invoking `command_loop_2()', `initial_command_loop()' calls -`top_level_1()', which handles all of the startup stuff (creating the -initial frame, handling the command-line options, loading the user's -`.emacs' file, etc.). The function that actually does this is in Lisp -and is pointed to by the variable `top-level'; normally this function is -`normal-top-level'. `top_level_1()' is just an error-handling wrapper -similar to `command_loop_2()'. Note also that `initial_command_loop()' -sets up a catch for `top-level' when invoking `top_level_1()', just -like when it invokes `command_loop_2()'. - - -File: internals.info, Node: Specifics of the Event Gathering Mechanism, Next: Specifics About the Emacs Event, Prev: Main Loop, Up: Events and the Event Loop - -Specifics of the Event Gathering Mechanism -========================================== - - Here is an approximate diagram of the collection processes at work -in XEmacs, under TTY's (TTY's are simpler than X so we'll look at this -first): - - asynch. asynch. asynch. asynch. [Collectors in - kbd events kbd events process process the OS] - | | output output - | | | | - | | | | SIGINT, [signal handlers - | | | | SIGQUIT, in XEmacs] - V V V V SIGWINCH, - file file file file SIGALRM - desc. desc. desc. desc. | - (TTY) (TTY) (pipe) (pipe) | - | | | | fake timeouts - | | | | file | - | | | | desc. | - | | | | (pipe) | - | | | | | | - | | | | | | - | | | | | | - V V V V V V - ------>-----------<----------------<---------------- - | - | - | [collected using select() in emacs_tty_next_event() - | and converted to the appropriate Emacs event] - | - | - V (above this line is TTY-specific) - Emacs ----------------------------------------------- - event (below this line is the generic event mechanism) - | - | - was there if not, call - a SIGINT? emacs_tty_next_event() - | | - | | - | | - V V - --->------<---- - | - | [collected in event_stream_next_event(); - | SIGINT is converted using maybe_read_quit_event()] - V - Emacs - event - | - \---->------>----- maybe_kbd_translate() ---->---\ - | - | - | - command event queue | - if not from command - (contains events that were event queue, call - read earlier but not processed, event_stream_next_event() - typically when waiting in a | - sit-for, sleep-for, etc. for | - a particular event to be received) | - | | - | | - V V - ---->------------------------------------<---- - | - | [collected in - | next_event_internal()] - | - unread- unread- event from | - command- command- keyboard else, call - events event macro next_event_internal() - | | | | - | | | | - | | | | - V V V V - --------->----------------------<------------ - | - | [collected in `next-event', which may loop - | more than once if the event it gets is on - | a dead frame, device, etc.] - | - | - V - feed into top-level event loop, - which repeatedly calls `next-event' - and then dispatches the event - using `dispatch-event' - - Notice the separation between TTY-specific and generic event -mechanism. When using the Xt-based event loop, the TTY-specific stuff -is replaced but the rest stays the same. - - It's also important to realize that only one different kind of -system-specific event loop can be operating at a time, and must be able -to receive all kinds of events simultaneously. For the two existing -event loops (implemented in `event-tty.c' and `event-Xt.c', -respectively), the TTY event loop _only_ handles TTY consoles, while -the Xt event loop handles _both_ TTY and X consoles. This situation is -different from all of the output handlers, where you simply have one -per console type. - - Here's the Xt Event Loop Diagram (notice that below a certain point, -it's the same as the above diagram): - - asynch. asynch. asynch. asynch. [Collectors in - kbd kbd process process the OS] - events events output output - | | | | - | | | | asynch. asynch. [Collectors in the - | | | | X X OS and X Window System] - | | | | events events - | | | | | | - | | | | | | - | | | | | | SIGINT, [signal handlers - | | | | | | SIGQUIT, in XEmacs] - | | | | | | SIGWINCH, - | | | | | | SIGALRM - | | | | | | | - | | | | | | | - | | | | | | | timeouts - | | | | | | | | - | | | | | | | | - | | | | | | V | - V V V V V V fake | - file file file file file file file | - desc. desc. desc. desc. desc. desc. desc. | - (TTY) (TTY) (pipe) (pipe) (socket) (socket) (pipe) | - | | | | | | | | - | | | | | | | | - | | | | | | | | - V V V V V V V V - --->----------------------------------------<---------<------ - | | | - | | |[collected using select() in - | | | _XtWaitForSomething(), called - | | | from XtAppProcessEvent(), called - | | | in emacs_Xt_next_event(); - | | | dispatched to various callbacks] - | | | - | | | - emacs_Xt_ p_s_callback(), | [popup_selection_callback] - event_handler() x_u_v_s_callback(),| [x_update_vertical_scrollbar_ - | x_u_h_s_callback(),| callback] - | search_callback() | [x_update_horizontal_scrollbar_ - | | | callback] - | | | - | | | - enqueue_Xt_ signal_special_ | - dispatch_event() Xt_user_event() | - [maybe multiple | | - times, maybe 0 | | - times] | | - | enqueue_Xt_ | - | dispatch_event() | - | | | - | | | - V V | - -->----------<-- | - | | - | | - dispatch Xt_what_callback() - event sets flags - queue | - | | - | | - | | - | | - ---->-----------<-------- - | - | - | [collected and converted as appropriate in - | emacs_Xt_next_event()] - | - | - V (above this line is Xt-specific) - Emacs ------------------------------------------------ - event (below this line is the generic event mechanism) - | - | - was there if not, call - a SIGINT? emacs_Xt_next_event() - | | - | | - | | - V V - --->-------<---- - | - | [collected in event_stream_next_event(); - | SIGINT is converted using maybe_read_quit_event()] - V - Emacs - event - | - \---->------>----- maybe_kbd_translate() -->-----\ - | - | - | - command event queue | - if not from command - (contains events that were event queue, call - read earlier but not processed, event_stream_next_event() - typically when waiting in a | - sit-for, sleep-for, etc. for | - a particular event to be received) | - | | - | | - V V - ---->----------------------------------<------ - | - | [collected in - | next_event_internal()] - | - unread- unread- event from | - command- command- keyboard else, call - events event macro next_event_internal() - | | | | - | | | | - | | | | - V V V V - --------->----------------------<------------ - | - | [collected in `next-event', which may loop - | more than once if the event it gets is on - | a dead frame, device, etc.] - | - | - V - feed into top-level event loop, - which repeatedly calls `next-event' - and then dispatches the event - using `dispatch-event' - - -File: internals.info, Node: Specifics About the Emacs Event, Next: The Event Stream Callback Routines, Prev: Specifics of the Event Gathering Mechanism, Up: Events and the Event Loop - -Specifics About the Emacs Event -=============================== - - -File: internals.info, Node: The Event Stream Callback Routines, Next: Other Event Loop Functions, Prev: Specifics About the Emacs Event, Up: Events and the Event Loop - -The Event Stream Callback Routines -================================== - - -File: internals.info, Node: Other Event Loop Functions, Next: Converting Events, Prev: The Event Stream Callback Routines, Up: Events and the Event Loop - -Other Event Loop Functions -========================== - - `detect_input_pending()' and `input-pending-p' look for input by -calling `event_stream->event_pending_p' and looking in -`[V]unread-command-event' and the `command_event_queue' (they do not -check for an executing keyboard macro, though). - - `discard-input' cancels any command events pending (and any keyboard -macros currently executing), and puts the others onto the -`command_event_queue'. There is a comment about a "race condition", -which is not a good sign. - - `next-command-event' and `read-char' are higher-level interfaces to -`next-event'. `next-command-event' gets the next "command" event (i.e. -keypress, mouse event, menu selection, or scrollbar action), calling -`dispatch-event' on any others. `read-char' calls `next-command-event' -and uses `event_to_character()' to return the character equivalent. -With the right kind of input method support, it is possible for -(read-char) to return a Kanji character. - - -File: internals.info, Node: Converting Events, Next: Dispatching Events; The Command Builder, Prev: Other Event Loop Functions, Up: Events and the Event Loop - -Converting Events -================= - - `character_to_event()', `event_to_character()', -`event-to-character', and `character-to-event' convert between -characters and keypress events corresponding to the characters. If the -event was not a keypress, `event_to_character()' returns -1 and -`event-to-character' returns `nil'. These functions convert between -character representation and the split-up event representation (keysym -plus mod keys). - - -File: internals.info, Node: Dispatching Events; The Command Builder, Prev: Converting Events, Up: Events and the Event Loop - -Dispatching Events; The Command Builder -======================================= - - Not yet documented. - - -File: internals.info, Node: Evaluation; Stack Frames; Bindings, Next: Symbols and Variables, Prev: Events and the Event Loop, Up: Top - -Evaluation; Stack Frames; Bindings -********************************** - -* Menu: - -* Evaluation:: -* Dynamic Binding; The specbinding Stack; Unwind-Protects:: -* Simple Special Forms:: -* Catch and Throw:: - diff -u -r -N xemacs-21.4.14/info/internals.info-7 xemacs-21.4.15/info/internals.info-7 --- xemacs-21.4.14/info/internals.info-7 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-7 1969-12-31 19:00:00.000000000 -0500 @@ -1,1111 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Evaluation, Next: Dynamic Binding; The specbinding Stack; Unwind-Protects, Up: Evaluation; Stack Frames; Bindings - -Evaluation -========== - - `Feval()' evaluates the form (a Lisp object) that is passed to it. -Note that evaluation is only non-trivial for two types of objects: -symbols and conses. A symbol is evaluated simply by calling -`symbol-value' on it and returning the value. - - Evaluating a cons means calling a function. First, `eval' checks to -see if garbage-collection is necessary, and calls `garbage_collect_1()' -if so. It then increases the evaluation depth by 1 (`lisp_eval_depth', -which is always less than `max_lisp_eval_depth') and adds an element to -the linked list of `struct backtrace''s (`backtrace_list'). Each such -structure contains a pointer to the function being called plus a list -of the function's arguments. Originally these values are stored -unevalled, and as they are evaluated, the backtrace structure is -updated. Garbage collection pays attention to the objects pointed to -in the backtrace structures (garbage collection might happen while a -function is being called or while an argument is being evaluated, and -there could easily be no other references to the arguments in the -argument list; once an argument is evaluated, however, the unevalled -version is not needed by eval, and so the backtrace structure is -changed). - - At this point, the function to be called is determined by looking at -the car of the cons (if this is a symbol, its function definition is -retrieved and the process repeated). The function should then consist -of either a `Lisp_Subr' (built-in function written in C), a -`Lisp_Compiled_Function' object, or a cons whose car is one of the -symbols `autoload', `macro' or `lambda'. - - If the function is a `Lisp_Subr', the lisp object points to a -`struct Lisp_Subr' (created by `DEFUN()'), which contains a pointer to -the C function, a minimum and maximum number of arguments (or possibly -the special constants `MANY' or `UNEVALLED'), a pointer to the symbol -referring to that subr, and a couple of other things. If the subr -wants its arguments `UNEVALLED', they are passed raw as a list. -Otherwise, an array of evaluated arguments is created and put into the -backtrace structure, and either passed whole (`MANY') or each argument -is passed as a C argument. - - If the function is a `Lisp_Compiled_Function', -`funcall_compiled_function()' is called. If the function is a lambda -list, `funcall_lambda()' is called. If the function is a macro, [..... -fill in] is done. If the function is an autoload, `do_autoload()' is -called to load the definition and then eval starts over [explain this -more]. - - When `Feval()' exits, the evaluation depth is reduced by one, the -debugger is called if appropriate, and the current backtrace structure -is removed from the list. - - Both `funcall_compiled_function()' and `funcall_lambda()' need to go -through the list of formal parameters to the function and bind them to -the actual arguments, checking for `&rest' and `&optional' symbols in -the formal parameters and making sure the number of actual arguments is -correct. `funcall_compiled_function()' can do this a little more -efficiently, since the formal parameter list can be checked for sanity -when the compiled function object is created. - - `funcall_lambda()' simply calls `Fprogn' to execute the code in the -lambda list. - - `funcall_compiled_function()' calls the real byte-code interpreter -`execute_optimized_program()' on the byte-code instructions, which are -converted into an internal form for faster execution. - - When a compiled function is executed for the first time by -`funcall_compiled_function()', or during the dump phase of building -XEmacs, the byte-code instructions are converted from a `Lisp_String' -(which is inefficient to access, especially in the presence of MULE) -into a `Lisp_Opaque' object containing an array of unsigned char, which -can be directly executed by the byte-code interpreter. At this time -the byte code is also analyzed for validity and transformed into a more -optimized form, so that `execute_optimized_program()' can really fly. - - Here are some of the optimizations performed by the internal -byte-code transformer: - 1. References to the `constants' array are checked for out-of-range - indices, so that the byte interpreter doesn't have to. - - 2. References to the `constants' array that will be used as a Lisp - variable are checked for being correct non-constant (i.e. not `t', - `nil', or `keywordp') symbols, so that the byte interpreter - doesn't have to. - - 3. The maximum number of variable bindings in the byte-code is - pre-computed, so that space on the `specpdl' stack can be - pre-reserved once for the whole function execution. - - 4. All byte-code jumps are relative to the current program counter - instead of the start of the program, thereby saving a register. - - 5. One-byte relative jumps are converted from the byte-code form of - unsigned chars offset by 127 to machine-friendly signed chars. - - Of course, this transformation of the `instructions' should not be -visible to the user, so `Fcompiled_function_instructions()' needs to -know how to convert the optimized opaque object back into a Lisp string -that is identical to the original string from the `.elc' file. -(Actually, the resulting string may (rarely) contain slightly -different, yet equivalent, byte code.) - - `Ffuncall()' implements Lisp `funcall'. `(funcall fun x1 x2 x3 -...)' is equivalent to `(eval (list fun (quote x1) (quote x2) (quote -x3) ...))'. `Ffuncall()' contains its own code to do the evaluation, -however, and is very similar to `Feval()'. - - From the performance point of view, it is worth knowing that most of -the time in Lisp evaluation is spent executing `Lisp_Subr' and -`Lisp_Compiled_Function' objects via `Ffuncall()' (not `Feval()'). - - `Fapply()' implements Lisp `apply', which is very similar to -`funcall' except that if the last argument is a list, the result is the -same as if each of the arguments in the list had been passed separately. -`Fapply()' does some business to expand the last argument if it's a -list, then calls `Ffuncall()' to do the work. - - `apply1()', `call0()', `call1()', `call2()', and `call3()' call a -function, passing it the argument(s) given (the arguments are given as -separate C arguments rather than being passed as an array). `apply1()' -uses `Fapply()' while the others use `Ffuncall()' to do the real work. - - -File: internals.info, Node: Dynamic Binding; The specbinding Stack; Unwind-Protects, Next: Simple Special Forms, Prev: Evaluation, Up: Evaluation; Stack Frames; Bindings - -Dynamic Binding; The specbinding Stack; Unwind-Protects -======================================================= - - struct specbinding - { - Lisp_Object symbol; - Lisp_Object old_value; - Lisp_Object (*func) (Lisp_Object); /* for unwind-protect */ - }; - - `struct specbinding' is used for local-variable bindings and -unwind-protects. `specpdl' holds an array of `struct specbinding''s, -`specpdl_ptr' points to the beginning of the free bindings in the -array, `specpdl_size' specifies the total number of binding slots in -the array, and `max_specpdl_size' specifies the maximum number of -bindings the array can be expanded to hold. `grow_specpdl()' increases -the size of the `specpdl' array, multiplying its size by 2 but never -exceeding `max_specpdl_size' (except that if this number is less than -400, it is first set to 400). - - `specbind()' binds a symbol to a value and is used for local -variables and `let' forms. The symbol and its old value (which might -be `Qunbound', indicating no prior value) are recorded in the specpdl -array, and `specpdl_size' is increased by 1. - - `record_unwind_protect()' implements an "unwind-protect", which, -when placed around a section of code, ensures that some specified -cleanup routine will be executed even if the code exits abnormally -(e.g. through a `throw' or quit). `record_unwind_protect()' simply -adds a new specbinding to the `specpdl' array and stores the -appropriate information in it. The cleanup routine can either be a C -function, which is stored in the `func' field, or a `progn' form, which -is stored in the `old_value' field. - - `unbind_to()' removes specbindings from the `specpdl' array until -the specified position is reached. Each specbinding can be one of -three types: - - 1. an unwind-protect with a C cleanup function (`func' is not 0, and - `old_value' holds an argument to be passed to the function); - - 2. an unwind-protect with a Lisp form (`func' is 0, `symbol' is - `nil', and `old_value' holds the form to be executed with - `Fprogn()'); or - - 3. a local-variable binding (`func' is 0, `symbol' is not `nil', and - `old_value' holds the old value, which is stored as the symbol's - value). - - -File: internals.info, Node: Simple Special Forms, Next: Catch and Throw, Prev: Dynamic Binding; The specbinding Stack; Unwind-Protects, Up: Evaluation; Stack Frames; Bindings - -Simple Special Forms -==================== - - `or', `and', `if', `cond', `progn', `prog1', `prog2', `setq', -`quote', `function', `let*', `let', `while' - - All of these are very simple and work as expected, calling `Feval()' -or `Fprogn()' as necessary and (in the case of `let' and `let*') using -`specbind()' to create bindings and `unbind_to()' to undo the bindings -when finished. - - Note that, with the exception of `Fprogn', these functions are -typically called in real life only in interpreted code, since the byte -compiler knows how to convert calls to these functions directly into -byte code. - - -File: internals.info, Node: Catch and Throw, Prev: Simple Special Forms, Up: Evaluation; Stack Frames; Bindings - -Catch and Throw -=============== - - struct catchtag - { - Lisp_Object tag; - Lisp_Object val; - struct catchtag *next; - struct gcpro *gcpro; - jmp_buf jmp; - struct backtrace *backlist; - int lisp_eval_depth; - int pdlcount; - }; - - `catch' is a Lisp function that places a catch around a body of -code. A catch is a means of non-local exit from the code. When a catch -is created, a tag is specified, and executing a `throw' to this tag -will exit from the body of code caught with this tag, and its value will -be the value given in the call to `throw'. If there is no such call, -the code will be executed normally. - - Information pertaining to a catch is held in a `struct catchtag', -which is placed at the head of a linked list pointed to by `catchlist'. -`internal_catch()' is passed a C function to call (`Fprogn()' when -Lisp `catch' is called) and arguments to give it, and places a catch -around the function. Each `struct catchtag' is held in the stack frame -of the `internal_catch()' instance that created the catch. - - `internal_catch()' is fairly straightforward. It stores into the -`struct catchtag' the tag name and the current values of -`backtrace_list', `lisp_eval_depth', `gcprolist', and the offset into -the `specpdl' array, sets a jump point with `_setjmp()' (storing the -jump point into the `struct catchtag'), and calls the function. -Control will return to `internal_catch()' either when the function -exits normally or through a `_longjmp()' to this jump point. In the -latter case, `throw' will store the value to be returned into the -`struct catchtag' before jumping. When it's done, `internal_catch()' -removes the `struct catchtag' from the catchlist and returns the proper -value. - - `Fthrow()' goes up through the catchlist until it finds one with a -matching tag. It then calls `unbind_catch()' to restore everything to -what it was when the appropriate catch was set, stores the return value -in the `struct catchtag', and jumps (with `_longjmp()') to its jump -point. - - `unbind_catch()' removes all catches from the catchlist until it -finds the correct one. Some of the catches might have been placed for -error-trapping, and if so, the appropriate entries on the handlerlist -must be removed (see "errors"). `unbind_catch()' also restores the -values of `gcprolist', `backtrace_list', and `lisp_eval', and calls -`unbind_to()' to undo any specbindings created since the catch. - - -File: internals.info, Node: Symbols and Variables, Next: Buffers and Textual Representation, Prev: Evaluation; Stack Frames; Bindings, Up: Top - -Symbols and Variables -********************* - -* Menu: - -* Introduction to Symbols:: -* Obarrays:: -* Symbol Values:: - - -File: internals.info, Node: Introduction to Symbols, Next: Obarrays, Up: Symbols and Variables - -Introduction to Symbols -======================= - - A symbol is basically just an object with four fields: a name (a -string), a value (some Lisp object), a function (some Lisp object), and -a property list (usually a list of alternating keyword/value pairs). -What makes symbols special is that there is usually only one symbol with -a given name, and the symbol is referred to by name. This makes a -symbol a convenient way of calling up data by name, i.e. of implementing -variables. (The variable's value is stored in the "value slot".) -Similarly, functions are referenced by name, and the definition of the -function is stored in a symbol's "function slot". This means that -there can be a distinct function and variable with the same name. The -property list is used as a more general mechanism of associating -additional values with particular names, and once again the namespace is -independent of the function and variable namespaces. - - -File: internals.info, Node: Obarrays, Next: Symbol Values, Prev: Introduction to Symbols, Up: Symbols and Variables - -Obarrays -======== - - The identity of symbols with their names is accomplished through a -structure called an obarray, which is just a poorly-implemented hash -table mapping from strings to symbols whose name is that string. (I say -"poorly implemented" because an obarray appears in Lisp as a vector -with some hidden fields rather than as its own opaque type. This is an -Emacs Lisp artifact that should be fixed.) - - Obarrays are implemented as a vector of some fixed size (which should -be a prime for best results), where each "bucket" of the vector -contains one or more symbols, threaded through a hidden `next' field in -the symbol. Lookup of a symbol in an obarray, and adding a symbol to -an obarray, is accomplished through standard hash-table techniques. - - The standard Lisp function for working with symbols and obarrays is -`intern'. This looks up a symbol in an obarray given its name; if it's -not found, a new symbol is automatically created with the specified -name, added to the obarray, and returned. This is what happens when the -Lisp reader encounters a symbol (or more precisely, encounters the name -of a symbol) in some text that it is reading. There is a standard -obarray called `obarray' that is used for this purpose, although the -Lisp programmer is free to create his own obarrays and `intern' symbols -in them. - - Note that, once a symbol is in an obarray, it stays there until -something is done about it, and the standard obarray `obarray' always -stays around, so once you use any particular variable name, a -corresponding symbol will stay around in `obarray' until you exit -XEmacs. - - Note that `obarray' itself is a variable, and as such there is a -symbol in `obarray' whose name is `"obarray"' and which contains -`obarray' as its value. - - Note also that this call to `intern' occurs only when in the Lisp -reader, not when the code is executed (at which point the symbol is -already around, stored as such in the definition of the function). - - You can create your own obarray using `make-vector' (this is -horrible but is an artifact) and intern symbols into that obarray. -Doing that will result in two or more symbols with the same name. -However, at most one of these symbols is in the standard `obarray': You -cannot have two symbols of the same name in any particular obarray. -Note that you cannot add a symbol to an obarray in any fashion other -than using `intern': i.e. you can't take an existing symbol and put it -in an existing obarray. Nor can you change the name of an existing -symbol. (Since obarrays are vectors, you can violate the consistency of -things by storing directly into the vector, but let's ignore that -possibility.) - - Usually symbols are created by `intern', but if you really want, you -can explicitly create a symbol using `make-symbol', giving it some -name. The resulting symbol is not in any obarray (i.e. it is -"uninterned"), and you can't add it to any obarray. Therefore its -primary purpose is as a symbol to use in macros to avoid namespace -pollution. It can also be used as a carrier of information, but cons -cells could probably be used just as well. - - You can also use `intern-soft' to look up a symbol but not create a -new one, and `unintern' to remove a symbol from an obarray. This -returns the removed symbol. (Remember: You can't put the symbol back -into any obarray.) Finally, `mapatoms' maps over all of the symbols in -an obarray. - - -File: internals.info, Node: Symbol Values, Prev: Obarrays, Up: Symbols and Variables - -Symbol Values -============= - - The value field of a symbol normally contains a Lisp object. -However, a symbol can be "unbound", meaning that it logically has no -value. This is internally indicated by storing a special Lisp object, -called "the unbound marker" and stored in the global variable -`Qunbound'. The unbound marker is of a special Lisp object type called -"symbol-value-magic". It is impossible for the Lisp programmer to -directly create or access any object of this type. - - *You must not let any "symbol-value-magic" object escape to the Lisp -level.* Printing any of these objects will cause the message `INTERNAL -EMACS BUG' to appear as part of the print representation. (You may see -this normally when you call `debug_print()' from the debugger on a Lisp -object.) If you let one of these objects escape to the Lisp level, you -will violate a number of assumptions contained in the C code and make -the unbound marker not function right. - - When a symbol is created, its value field (and function field) are -set to `Qunbound'. The Lisp programmer can restore these conditions -later using `makunbound' or `fmakunbound', and can query to see whether -the value of function fields are "bound" (i.e. have a value other than -`Qunbound') using `boundp' and `fboundp'. The fields are set to a -normal Lisp object using `set' (or `setq') and `fset'. - - Other symbol-value-magic objects are used as special markers to -indicate variables that have non-normal properties. This includes any -variables that are tied into C variables (setting the variable magically -sets some global variable in the C code, and likewise for retrieving the -variable's value), variables that magically tie into slots in the -current buffer, variables that are buffer-local, etc. The -symbol-value-magic object is stored in the value cell in place of a -normal object, and the code to retrieve a symbol's value (i.e. -`symbol-value') knows how to do special things with them. This means -that you should not just fetch the value cell directly if you want a -symbol's value. - - The exact workings of this are rather complex and involved and are -well-documented in comments in `buffer.c', `symbols.c', and `lisp.h'. - - -File: internals.info, Node: Buffers and Textual Representation, Next: MULE Character Sets and Encodings, Prev: Symbols and Variables, Up: Top - -Buffers and Textual Representation -********************************** - -* Menu: - -* Introduction to Buffers:: A buffer holds a block of text such as a file. -* The Text in a Buffer:: Representation of the text in a buffer. -* Buffer Lists:: Keeping track of all buffers. -* Markers and Extents:: Tagging locations within a buffer. -* Bufbytes and Emchars:: Representation of individual characters. -* The Buffer Object:: The Lisp object corresponding to a buffer. - - -File: internals.info, Node: Introduction to Buffers, Next: The Text in a Buffer, Up: Buffers and Textual Representation - -Introduction to Buffers -======================= - - A buffer is logically just a Lisp object that holds some text. In -this, it is like a string, but a buffer is optimized for frequent -insertion and deletion, while a string is not. Furthermore: - - 1. Buffers are "permanent" objects, i.e. once you create them, they - remain around, and need to be explicitly deleted before they go - away. - - 2. Each buffer has a unique name, which is a string. Buffers are - normally referred to by name. In this respect, they are like - symbols. - - 3. Buffers have a default insertion position, called "point". - Inserting text (unless you explicitly give a position) goes at - point, and moves point forward past the text. This is what is - going on when you type text into Emacs. - - 4. Buffers have lots of extra properties associated with them. - - 5. Buffers can be "displayed". What this means is that there exist a - number of "windows", which are objects that correspond to some - visible section of your display, and each window has an associated - buffer, and the current contents of the buffer are shown in that - section of the display. The redisplay mechanism (which takes care - of doing this) knows how to look at the text of a buffer and come - up with some reasonable way of displaying this. Many of the - properties of a buffer control how the buffer's text is displayed. - - 6. One buffer is distinguished and called the "current buffer". It is - stored in the variable `current_buffer'. Buffer operations operate - on this buffer by default. When you are typing text into a - buffer, the buffer you are typing into is always `current_buffer'. - Switching to a different window changes the current buffer. Note - that Lisp code can temporarily change the current buffer using - `set-buffer' (often enclosed in a `save-excursion' so that the - former current buffer gets restored when the code is finished). - However, calling `set-buffer' will NOT cause a permanent change in - the current buffer. The reason for this is that the top-level - event loop sets `current_buffer' to the buffer of the selected - window, each time it finishes executing a user command. - - Make sure you understand the distinction between "current buffer" -and "buffer of the selected window", and the distinction between -"point" of the current buffer and "window-point" of the selected -window. (This latter distinction is explained in detail in the section -on windows.) - - -File: internals.info, Node: The Text in a Buffer, Next: Buffer Lists, Prev: Introduction to Buffers, Up: Buffers and Textual Representation - -The Text in a Buffer -==================== - - The text in a buffer consists of a sequence of zero or more -characters. A "character" is an integer that logically represents a -letter, number, space, or other unit of text. Most of the characters -that you will typically encounter belong to the ASCII set of characters, -but there are also characters for various sorts of accented letters, -special symbols, Chinese and Japanese ideograms (i.e. Kanji, Katakana, -etc.), Cyrillic and Greek letters, etc. The actual number of possible -characters is quite large. - - For now, we can view a character as some non-negative integer that -has some shape that defines how it typically appears (e.g. as an -uppercase A). (The exact way in which a character appears depends on the -font used to display the character.) The internal type of characters in -the C code is an `Emchar'; this is just an `int', but using a symbolic -type makes the code clearer. - - Between every character in a buffer is a "buffer position" or -"character position". We can speak of the character before or after a -particular buffer position, and when you insert a character at a -particular position, all characters after that position end up at new -positions. When we speak of the character "at" a position, we really -mean the character after the position. (This schizophrenia between a -buffer position being "between" a character and "on" a character is -rampant in Emacs.) - - Buffer positions are numbered starting at 1. This means that -position 1 is before the first character, and position 0 is not valid. -If there are N characters in a buffer, then buffer position N+1 is -after the last one, and position N+2 is not valid. - - The internal makeup of the Emchar integer varies depending on whether -we have compiled with MULE support. If not, the Emchar integer is an -8-bit integer with possible values from 0 - 255. 0 - 127 are the -standard ASCII characters, while 128 - 255 are the characters from the -ISO-8859-1 character set. If we have compiled with MULE support, an -Emchar is a 19-bit integer, with the various bits having meanings -according to a complex scheme that will be detailed later. The -characters numbered 0 - 255 still have the same meanings as for the -non-MULE case, though. - - Internally, the text in a buffer is represented in a fairly simple -fashion: as a contiguous array of bytes, with a "gap" of some size in -the middle. Although the gap is of some substantial size in bytes, -there is no text contained within it: From the perspective of the text -in the buffer, it does not exist. The gap logically sits at some buffer -position, between two characters (or possibly at the beginning or end of -the buffer). Insertion of text in a buffer at a particular position is -always accomplished by first moving the gap to that position (i.e. -through some block moving of text), then writing the text into the -beginning of the gap, thereby shrinking the gap. If the gap shrinks -down to nothing, a new gap is created. (What actually happens is that a -new gap is "created" at the end of the buffer's text, which requires -nothing more than changing a couple of indices; then the gap is "moved" -to the position where the insertion needs to take place by moving up in -memory all the text after that position.) Similarly, deletion occurs -by moving the gap to the place where the text is to be deleted, and -then simply expanding the gap to include the deleted text. -("Expanding" and "shrinking" the gap as just described means just that -the internal indices that keep track of where the gap is located are -changed.) - - Note that the total amount of memory allocated for a buffer text -never decreases while the buffer is live. Therefore, if you load up a -20-megabyte file and then delete all but one character, there will be a -20-megabyte gap, which won't get any smaller (except by inserting -characters back again). Once the buffer is killed, the memory allocated -for the buffer text will be freed, but it will still be sitting on the -heap, taking up virtual memory, and will not be released back to the -operating system. (However, if you have compiled XEmacs with rel-alloc, -the situation is different. In this case, the space _will_ be released -back to the operating system. However, this tends to result in a -noticeable speed penalty.) - - Astute readers may notice that the text in a buffer is represented as -an array of _bytes_, while (at least in the MULE case) an Emchar is a -19-bit integer, which clearly cannot fit in a byte. This means (of -course) that the text in a buffer uses a different representation from -an Emchar: specifically, the 19-bit Emchar becomes a series of one to -four bytes. The conversion between these two representations is complex -and will be described later. - - In the non-MULE case, everything is very simple: An Emchar is an -8-bit value, which fits neatly into one byte. - - If we are given a buffer position and want to retrieve the character -at that position, we need to follow these steps: - - 1. Pretend there's no gap, and convert the buffer position into a - "byte index" that indexes to the appropriate byte in the buffer's - stream of textual bytes. By convention, byte indices begin at 1, - just like buffer positions. In the non-MULE case, byte indices - and buffer positions are identical, since one character equals one - byte. - - 2. Convert the byte index into a "memory index", which takes the gap - into account. The memory index is a direct index into the block of - memory that stores the text of a buffer. This basically just - involves checking to see if the byte index is past the gap, and if - so, adding the size of the gap to it. By convention, memory - indices begin at 1, just like buffer positions and byte indices, - and when referring to the position that is "at" the gap, we always - use the memory position at the _beginning_, not at the end, of the - gap. - - 3. Fetch the appropriate bytes at the determined memory position. - - 4. Convert these bytes into an Emchar. - - In the non-Mule case, (3) and (4) boil down to a simple one-byte -memory access. - - Note that we have defined three types of positions in a buffer: - - 1. "buffer positions" or "character positions", typedef `Bufpos' - - 2. "byte indices", typedef `Bytind' - - 3. "memory indices", typedef `Memind' - - All three typedefs are just `int's, but defining them this way makes -things a lot clearer. - - Most code works with buffer positions. In particular, all Lisp code -that refers to text in a buffer uses buffer positions. Lisp code does -not know that byte indices or memory indices exist. - - Finally, we have a typedef for the bytes in a buffer. This is a -`Bufbyte', which is an unsigned char. Referring to them as Bufbytes -underscores the fact that we are working with a string of bytes in the -internal Emacs buffer representation rather than in one of a number of -possible alternative representations (e.g. EUC-encoded text, etc.). - - -File: internals.info, Node: Buffer Lists, Next: Markers and Extents, Prev: The Text in a Buffer, Up: Buffers and Textual Representation - -Buffer Lists -============ - - Recall earlier that buffers are "permanent" objects, i.e. that they -remain around until explicitly deleted. This entails that there is a -list of all the buffers in existence. This list is actually an -assoc-list (mapping from the buffer's name to the buffer) and is stored -in the global variable `Vbuffer_alist'. - - The order of the buffers in the list is important: the buffers are -ordered approximately from most-recently-used to least-recently-used. -Switching to a buffer using `switch-to-buffer', `pop-to-buffer', etc. -and switching windows using `other-window', etc. usually brings the -new current buffer to the front of the list. `switch-to-buffer', -`other-buffer', etc. look at the beginning of the list to find an -alternative buffer to suggest. You can also explicitly move a buffer -to the end of the list using `bury-buffer'. - - In addition to the global ordering in `Vbuffer_alist', each frame -has its own ordering of the list. These lists always contain the same -elements as in `Vbuffer_alist' although possibly in a different order. -`buffer-list' normally returns the list for the selected frame. This -allows you to work in separate frames without things interfering with -each other. - - The standard way to look up a buffer given a name is `get-buffer', -and the standard way to create a new buffer is `get-buffer-create', -which looks up a buffer with a given name, creating a new one if -necessary. These operations correspond exactly with the symbol -operations `intern-soft' and `intern', respectively. You can also -force a new buffer to be created using `generate-new-buffer', which -takes a name and (if necessary) makes a unique name from this by -appending a number, and then creates the buffer. This is basically -like the symbol operation `gensym'. - - -File: internals.info, Node: Markers and Extents, Next: Bufbytes and Emchars, Prev: Buffer Lists, Up: Buffers and Textual Representation - -Markers and Extents -=================== - - Among the things associated with a buffer are things that are -logically attached to certain buffer positions. This can be used to -keep track of a buffer position when text is inserted and deleted, so -that it remains at the same spot relative to the text around it; to -assign properties to particular sections of text; etc. There are two -such objects that are useful in this regard: they are "markers" and -"extents". - - A "marker" is simply a flag placed at a particular buffer position, -which is moved around as text is inserted and deleted. Markers are -used for all sorts of purposes, such as the `mark' that is the other -end of textual regions to be cut, copied, etc. - - An "extent" is similar to two markers plus some associated -properties, and is used to keep track of regions in a buffer as text is -inserted and deleted, and to add properties (e.g. fonts) to particular -regions of text. The external interface of extents is explained -elsewhere. - - The important thing here is that markers and extents simply contain -buffer positions in them as integers, and every time text is inserted or -deleted, these positions must be updated. In order to minimize the -amount of shuffling that needs to be done, the positions in markers and -extents (there's one per marker, two per extent) are stored in Meminds. -This means that they only need to be moved when the text is physically -moved in memory; since the gap structure tries to minimize this, it also -minimizes the number of marker and extent indices that need to be -adjusted. Look in `insdel.c' for the details of how this works. - - One other important distinction is that markers are "temporary" -while extents are "permanent". This means that markers disappear as -soon as there are no more pointers to them, and correspondingly, there -is no way to determine what markers are in a buffer if you are just -given the buffer. Extents remain in a buffer until they are detached -(which could happen as a result of text being deleted) or the buffer is -deleted, and primitives do exist to enumerate the extents in a buffer. - - -File: internals.info, Node: Bufbytes and Emchars, Next: The Buffer Object, Prev: Markers and Extents, Up: Buffers and Textual Representation - -Bufbytes and Emchars -==================== - - Not yet documented. - - -File: internals.info, Node: The Buffer Object, Prev: Bufbytes and Emchars, Up: Buffers and Textual Representation - -The Buffer Object -================= - - Buffers contain fields not directly accessible by the Lisp -programmer. We describe them here, naming them by the names used in -the C code. Many are accessible indirectly in Lisp programs via Lisp -primitives. - -`name' - The buffer name is a string that names the buffer. It is - guaranteed to be unique. *Note Buffer Names: (lispref)Buffer - Names. - -`save_modified' - This field contains the time when the buffer was last saved, as an - integer. *Note Buffer Modification: (lispref)Buffer Modification. - -`modtime' - This field contains the modification time of the visited file. It - is set when the file is written or read. Every time the buffer is - written to the file, this field is compared to the modification - time of the file. *Note Buffer Modification: (lispref)Buffer - Modification. - -`auto_save_modified' - This field contains the time when the buffer was last auto-saved. - -`last_window_start' - This field contains the `window-start' position in the buffer as of - the last time the buffer was displayed in a window. - -`undo_list' - This field points to the buffer's undo list. *Note Undo: - (lispref)Undo. - -`syntax_table_v' - This field contains the syntax table for the buffer. *Note Syntax - Tables: (lispref)Syntax Tables. - -`downcase_table' - This field contains the conversion table for converting text to - lower case. *Note Case Tables: (lispref)Case Tables. - -`upcase_table' - This field contains the conversion table for converting text to - upper case. *Note Case Tables: (lispref)Case Tables. - -`case_canon_table' - This field contains the conversion table for canonicalizing text - for case-folding search. *Note Case Tables: (lispref)Case Tables. - -`case_eqv_table' - This field contains the equivalence table for case-folding search. - *Note Case Tables: (lispref)Case Tables. - -`display_table' - This field contains the buffer's display table, or `nil' if it - doesn't have one. *Note Display Tables: (lispref)Display Tables. - -`markers' - This field contains the chain of all markers that currently point - into the buffer. Deletion of text in the buffer, and motion of - the buffer's gap, must check each of these markers and perhaps - update it. *Note Markers: (lispref)Markers. - -`backed_up' - This field is a flag that tells whether a backup file has been - made for the visited file of this buffer. - -`mark' - This field contains the mark for the buffer. The mark is a marker, - hence it is also included on the list `markers'. *Note The Mark: - (lispref)The Mark. - -`mark_active' - This field is non-`nil' if the buffer's mark is active. - -`local_var_alist' - This field contains the association list describing the variables - local in this buffer, and their values, with the exception of - local variables that have special slots in the buffer object. - (Those slots are omitted from this table.) *Note Buffer-Local - Variables: (lispref)Buffer-Local Variables. - -`modeline_format' - This field contains a Lisp object which controls how to display - the mode line for this buffer. *Note Modeline Format: - (lispref)Modeline Format. - -`base_buffer' - This field holds the buffer's base buffer (if it is an indirect - buffer), or `nil'. - - -File: internals.info, Node: MULE Character Sets and Encodings, Next: The Lisp Reader and Compiler, Prev: Buffers and Textual Representation, Up: Top - -MULE Character Sets and Encodings -********************************* - - Recall that there are two primary ways that text is represented in -XEmacs. The "buffer" representation sees the text as a series of bytes -(Bufbytes), with a variable number of bytes used per character. The -"character" representation sees the text as a series of integers -(Emchars), one per character. The character representation is a cleaner -representation from a theoretical standpoint, and is thus used in many -cases when lots of manipulations on a string need to be done. However, -the buffer representation is the standard representation used in both -Lisp strings and buffers, and because of this, it is the "default" -representation that text comes in. The reason for using this -representation is that it's compact and is compatible with ASCII. - -* Menu: - -* Character Sets:: -* Encodings:: -* Internal Mule Encodings:: -* CCL:: - - -File: internals.info, Node: Character Sets, Next: Encodings, Up: MULE Character Sets and Encodings - -Character Sets -============== - - A character set (or "charset") is an ordered set of characters. A -particular character in a charset is indexed using one or more -"position codes", which are non-negative integers. The number of -position codes needed to identify a particular character in a charset is -called the "dimension" of the charset. In XEmacs/Mule, all charsets -have dimension 1 or 2, and the size of all charsets (except for a few -special cases) is either 94, 96, 94 by 94, or 96 by 96. The range of -position codes used to index characters from any of these types of -character sets is as follows: - - Charset type Position code 1 Position code 2 - ------------------------------------------------------------ - 94 33 - 126 N/A - 96 32 - 127 N/A - 94x94 33 - 126 33 - 126 - 96x96 32 - 127 32 - 127 - - Note that in the above cases position codes do not start at an -expected value such as 0 or 1. The reason for this will become clear -later. - - For example, Latin-1 is a 96-character charset, and JISX0208 (the -Japanese national character set) is a 94x94-character charset. - - [Note that, although the ranges above define the _valid_ position -codes for a charset, some of the slots in a particular charset may in -fact be empty. This is the case for JISX0208, for example, where (e.g.) -all the slots whose first position code is in the range 118 - 127 are -empty.] - - There are three charsets that do not follow the above rules. All of -them have one dimension, and have ranges of position codes as follows: - - Charset name Position code 1 - ------------------------------------ - ASCII 0 - 127 - Control-1 0 - 31 - Composite 0 - some large number - - (The upper bound of the position code for composite characters has -not yet been determined, but it will probably be at least 16,383). - - ASCII is the union of two subsidiary character sets: Printing-ASCII -(the printing ASCII character set, consisting of position codes 33 - -126, like for a standard 94-character charset) and Control-ASCII (the -non-printing characters that would appear in a binary file with codes 0 -- 32 and 127). - - Control-1 contains the non-printing characters that would appear in a -binary file with codes 128 - 159. - - Composite contains characters that are generated by overstriking one -or more characters from other charsets. - - Note that some characters in ASCII, and all characters in Control-1, -are "control" (non-printing) characters. These have no printed -representation but instead control some other function of the printing -(e.g. TAB or 8 moves the current character position to the next tab -stop). All other characters in all charsets are "graphic" (printing) -characters. - - When a binary file is read in, the bytes in the file are assigned to -character sets as follows: - - Bytes Character set Range - -------------------------------------------------- - 0 - 127 ASCII 0 - 127 - 128 - 159 Control-1 0 - 31 - 160 - 255 Latin-1 32 - 127 - - This is a bit ad-hoc but gets the job done. - - -File: internals.info, Node: Encodings, Next: Internal Mule Encodings, Prev: Character Sets, Up: MULE Character Sets and Encodings - -Encodings -========= - - An "encoding" is a way of numerically representing characters from -one or more character sets. If an encoding only encompasses one -character set, then the position codes for the characters in that -character set could be used directly. This is not possible, however, if -more than one character set is to be used in the encoding. - - For example, the conversion detailed above between bytes in a binary -file and characters is effectively an encoding that encompasses the -three character sets ASCII, Control-1, and Latin-1 in a stream of 8-bit -bytes. - - Thus, an encoding can be viewed as a way of encoding characters from -a specified group of character sets using a stream of bytes, each of -which contains a fixed number of bits (but not necessarily 8, as in the -common usage of "byte"). - - Here are descriptions of a couple of common encodings: - -* Menu: - -* Japanese EUC (Extended Unix Code):: -* JIS7:: - - -File: internals.info, Node: Japanese EUC (Extended Unix Code), Next: JIS7, Up: Encodings - -Japanese EUC (Extended Unix Code) ---------------------------------- - - This encompasses the character sets Printing-ASCII, -Japanese-JISX0201, and Japanese-JISX0208-Kana (half-width katakana, the -right half of JISX0201). It uses 8-bit bytes. - - Note that Printing-ASCII and Japanese-JISX0201-Kana are 94-character -charsets, while Japanese-JISX0208 is a 94x94-character charset. - - The encoding is as follows: - - Character set Representation (PC=position-code) - ------------- -------------- - Printing-ASCII PC1 - Japanese-JISX0201-Kana 0x8E | PC1 + 0x80 - Japanese-JISX0208 PC1 + 0x80 | PC2 + 0x80 - Japanese-JISX0212 PC1 + 0x80 | PC2 + 0x80 - - -File: internals.info, Node: JIS7, Prev: Japanese EUC (Extended Unix Code), Up: Encodings - -JIS7 ----- - - This encompasses the character sets Printing-ASCII, -Japanese-JISX0201-Roman (the left half of JISX0201; this character set -is very similar to Printing-ASCII and is a 94-character charset), -Japanese-JISX0208, and Japanese-JISX0201-Kana. It uses 7-bit bytes. - - Unlike Japanese EUC, this is a "modal" encoding, which means that -there are multiple states that the encoding can be in, which affect how -the bytes are to be interpreted. Special sequences of bytes (called -"escape sequences") are used to change states. - - The encoding is as follows: - - Character set Representation (PC=position-code) - ------------- -------------- - Printing-ASCII PC1 - Japanese-JISX0201-Roman PC1 - Japanese-JISX0201-Kana PC1 - Japanese-JISX0208 PC1 PC2 - - - Escape sequence ASCII equivalent Meaning - --------------- ---------------- ------- - 0x1B 0x28 0x4A ESC ( J invoke Japanese-JISX0201-Roman - 0x1B 0x28 0x49 ESC ( I invoke Japanese-JISX0201-Kana - 0x1B 0x24 0x42 ESC $ B invoke Japanese-JISX0208 - 0x1B 0x28 0x42 ESC ( B invoke Printing-ASCII - - Initially, Printing-ASCII is invoked. - - -File: internals.info, Node: Internal Mule Encodings, Next: CCL, Prev: Encodings, Up: MULE Character Sets and Encodings - -Internal Mule Encodings -======================= - - In XEmacs/Mule, each character set is assigned a unique number, -called a "leading byte". This is used in the encodings of a character. -Leading bytes are in the range 0x80 - 0xFF (except for ASCII, which has -a leading byte of 0), although some leading bytes are reserved. - - Charsets whose leading byte is in the range 0x80 - 0x9F are called -"official" and are used for built-in charsets. Other charsets are -called "private" and have leading bytes in the range 0xA0 - 0xFF; these -are user-defined charsets. - - More specifically: - - Character set Leading byte - ------------- ------------ - ASCII 0 - Composite 0x80 - Dimension-1 Official 0x81 - 0x8D - (0x8E is free) - Control-1 0x8F - Dimension-2 Official 0x90 - 0x99 - (0x9A - 0x9D are free; - 0x9E and 0x9F are reserved) - Dimension-1 Private 0xA0 - 0xEF - Dimension-2 Private 0xF0 - 0xFF - - There are two internal encodings for characters in XEmacs/Mule. One -is called "string encoding" and is an 8-bit encoding that is used for -representing characters in a buffer or string. It uses 1 to 4 bytes per -character. The other is called "character encoding" and is a 19-bit -encoding that is used for representing characters individually in a -variable. - - (In the following descriptions, we'll ignore composite characters for -the moment. We also give a general (structural) overview first, -followed later by the exact details.) - -* Menu: - -* Internal String Encoding:: -* Internal Character Encoding:: - - -File: internals.info, Node: Internal String Encoding, Next: Internal Character Encoding, Up: Internal Mule Encodings - -Internal String Encoding ------------------------- - - ASCII characters are encoded using their position code directly. -Other characters are encoded using their leading byte followed by their -position code(s) with the high bit set. Characters in private character -sets have their leading byte prefixed with a "leading byte prefix", -which is either 0x9E or 0x9F. (No character sets are ever assigned these -leading bytes.) Specifically: - - Character set Encoding (PC=position-code, LB=leading-byte) - ------------- -------- - ASCII PC-1 | - Control-1 LB | PC1 + 0xA0 | - Dimension-1 official LB | PC1 + 0x80 | - Dimension-1 private 0x9E | LB | PC1 + 0x80 | - Dimension-2 official LB | PC1 + 0x80 | PC2 + 0x80 | - Dimension-2 private 0x9F | LB | PC1 + 0x80 | PC2 + 0x80 - - The basic characteristic of this encoding is that the first byte of -all characters is in the range 0x00 - 0x9F, and the second and -following bytes of all characters is in the range 0xA0 - 0xFF. This -means that it is impossible to get out of sync, or more specifically: - - 1. Given any byte position, the beginning of the character it is - within can be determined in constant time. - - 2. Given any byte position at the beginning of a character, the - beginning of the next character can be determined in constant time. - - 3. Given any byte position at the beginning of a character, the - beginning of the previous character can be determined in constant - time. - - 4. Textual searches can simply treat encoded strings as if they were - encoded in a one-byte-per-character fashion rather than the actual - multi-byte encoding. - - None of the standard non-modal encodings meet all of these -conditions. For example, EUC satisfies only (2) and (3), while -Shift-JIS and Big5 (not yet described) satisfy only (2). (All non-modal -encodings must satisfy (2), in order to be unambiguous.) - diff -u -r -N xemacs-21.4.14/info/internals.info-8 xemacs-21.4.15/info/internals.info-8 --- xemacs-21.4.14/info/internals.info-8 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-8 1969-12-31 19:00:00.000000000 -0500 @@ -1,1207 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Internal Character Encoding, Prev: Internal String Encoding, Up: Internal Mule Encodings - -Internal Character Encoding ---------------------------- - - One 19-bit word represents a single character. The word is -separated into three fields: - - Bit number: 18 17 16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 - <------------> <------------------> <------------------> - Field: 1 2 3 - - Note that fields 2 and 3 hold 7 bits each, while field 1 holds 5 -bits. - - Character set Field 1 Field 2 Field 3 - ------------- ------- ------- ------- - ASCII 0 0 PC1 - range: (00 - 7F) - Control-1 0 1 PC1 - range: (00 - 1F) - Dimension-1 official 0 LB - 0x80 PC1 - range: (01 - 0D) (20 - 7F) - Dimension-1 private 0 LB - 0x80 PC1 - range: (20 - 6F) (20 - 7F) - Dimension-2 official LB - 0x8F PC1 PC2 - range: (01 - 0A) (20 - 7F) (20 - 7F) - Dimension-2 private LB - 0xE1 PC1 PC2 - range: (0F - 1E) (20 - 7F) (20 - 7F) - Composite 0x1F ? ? - - Note that character codes 0 - 255 are the same as the "binary -encoding" described above. - - -File: internals.info, Node: CCL, Prev: Internal Mule Encodings, Up: MULE Character Sets and Encodings - -CCL -=== - - CCL PROGRAM SYNTAX: - CCL_PROGRAM := (CCL_MAIN_BLOCK - [ CCL_EOF_BLOCK ]) - - CCL_MAIN_BLOCK := CCL_BLOCK - CCL_EOF_BLOCK := CCL_BLOCK - - CCL_BLOCK := STATEMENT | (STATEMENT [STATEMENT ...]) - STATEMENT := - SET | IF | BRANCH | LOOP | REPEAT | BREAK - | READ | WRITE - - SET := (REG = EXPRESSION) | (REG SELF_OP EXPRESSION) - | INT-OR-CHAR - - EXPRESSION := ARG | (EXPRESSION OP ARG) - - IF := (if EXPRESSION CCL_BLOCK CCL_BLOCK) - BRANCH := (branch EXPRESSION CCL_BLOCK [CCL_BLOCK ...]) - LOOP := (loop STATEMENT [STATEMENT ...]) - BREAK := (break) - REPEAT := (repeat) - | (write-repeat [REG | INT-OR-CHAR | string]) - | (write-read-repeat REG [INT-OR-CHAR | string | ARRAY]?) - READ := (read REG) | (read REG REG) - | (read-if REG ARITH_OP ARG CCL_BLOCK CCL_BLOCK) - | (read-branch REG CCL_BLOCK [CCL_BLOCK ...]) - WRITE := (write REG) | (write REG REG) - | (write INT-OR-CHAR) | (write STRING) | STRING - | (write REG ARRAY) - END := (end) - - REG := r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 - ARG := REG | INT-OR-CHAR - OP := + | - | * | / | % | & | '|' | ^ | << | >> | <8 | >8 | // - | < | > | == | <= | >= | != - SELF_OP := - += | -= | *= | /= | %= | &= | '|=' | ^= | <<= | >>= - ARRAY := '[' INT-OR-CHAR ... ']' - INT-OR-CHAR := INT | CHAR - - MACHINE CODE: - - The machine code consists of a vector of 32-bit words. - The first such word specifies the start of the EOF section of the code; - this is the code executed to handle any stuff that needs to be done - (e.g. designating back to ASCII and left-to-right mode) after all - other encoded/decoded data has been written out. This is not used for - charset CCL programs. - - REGISTER: 0..7 -- referred by RRR or rrr - - OPERATOR BIT FIELD (27-bit): XXXXXXXXXXXXXXX RRR TTTTT - TTTTT (5-bit): operator type - RRR (3-bit): register number - XXXXXXXXXXXXXXXX (15-bit): - CCCCCCCCCCCCCCC: constant or address - 000000000000rrr: register number - - AAAA: 00000 + - 00001 - - 00010 * - 00011 / - 00100 % - 00101 & - 00110 | - 00111 ~ - - 01000 << - 01001 >> - 01010 <8 - 01011 >8 - 01100 // - 01101 not used - 01110 not used - 01111 not used - - 10000 < - 10001 > - 10010 == - 10011 <= - 10100 >= - 10101 != - - OPERATORS: TTTTT RRR XX.. - - SetCS: 00000 RRR C...C RRR = C...C - SetCL: 00001 RRR ..... RRR = c...c - c.............c - SetR: 00010 RRR ..rrr RRR = rrr - SetA: 00011 RRR ..rrr RRR = array[rrr] - C.............C size of array = C...C - c.............c contents = c...c - - Jump: 00100 000 c...c jump to c...c - JumpCond: 00101 RRR c...c if (!RRR) jump to c...c - WriteJump: 00110 RRR c...c Write1 RRR, jump to c...c - WriteReadJump: 00111 RRR c...c Write1, Read1 RRR, jump to c...c - WriteCJump: 01000 000 c...c Write1 C...C, jump to c...c - C...C - WriteCReadJump: 01001 RRR c...c Write1 C...C, Read1 RRR, - C.............C and jump to c...c - WriteSJump: 01010 000 c...c WriteS, jump to c...c - C.............C - S.............S - ... - WriteSReadJump: 01011 RRR c...c WriteS, Read1 RRR, jump to c...c - C.............C - S.............S - ... - WriteAReadJump: 01100 RRR c...c WriteA, Read1 RRR, jump to c...c - C.............C size of array = C...C - c.............c contents = c...c - ... - Branch: 01101 RRR C...C if (RRR >= 0 && RRR < C..) - c.............c branch to (RRR+1)th address - Read1: 01110 RRR ... read 1-byte to RRR - Read2: 01111 RRR ..rrr read 2-byte to RRR and rrr - ReadBranch: 10000 RRR C...C Read1 and Branch - c.............c - ... - Write1: 10001 RRR ..... write 1-byte RRR - Write2: 10010 RRR ..rrr write 2-byte RRR and rrr - WriteC: 10011 000 ..... write 1-char C...CC - C.............C - WriteS: 10100 000 ..... write C..-byte of string - C.............C - S.............S - ... - WriteA: 10101 RRR ..... write array[RRR] - C.............C size of array = C...C - c.............c contents = c...c - ... - End: 10110 000 ..... terminate the execution - - SetSelfCS: 10111 RRR C...C RRR AAAAA= C...C - ..........AAAAA - SetSelfCL: 11000 RRR ..... RRR AAAAA= c...c - c.............c - ..........AAAAA - SetSelfR: 11001 RRR ..Rrr RRR AAAAA= rrr - ..........AAAAA - SetExprCL: 11010 RRR ..Rrr RRR = rrr AAAAA c...c - c.............c - ..........AAAAA - SetExprR: 11011 RRR ..rrr RRR = rrr AAAAA Rrr - ............Rrr - ..........AAAAA - JumpCondC: 11100 RRR c...c if !(RRR AAAAA C..) jump to c...c - C.............C - ..........AAAAA - JumpCondR: 11101 RRR c...c if !(RRR AAAAA rrr) jump to c...c - ............rrr - ..........AAAAA - ReadJumpCondC: 11110 RRR c...c Read1 and JumpCondC - C.............C - ..........AAAAA - ReadJumpCondR: 11111 RRR c...c Read1 and JumpCondR - ............rrr - ..........AAAAA - - -File: internals.info, Node: The Lisp Reader and Compiler, Next: Lstreams, Prev: MULE Character Sets and Encodings, Up: Top - -The Lisp Reader and Compiler -**************************** - - Not yet documented. - - -File: internals.info, Node: Lstreams, Next: Consoles; Devices; Frames; Windows, Prev: The Lisp Reader and Compiler, Up: Top - -Lstreams -******** - - An "lstream" is an internal Lisp object that provides a generic -buffering stream implementation. Conceptually, you send data to the -stream or read data from the stream, not caring what's on the other end -of the stream. The other end could be another stream, a file -descriptor, a stdio stream, a fixed block of memory, a reallocating -block of memory, etc. The main purpose of the stream is to provide a -standard interface and to do buffering. Macros are defined to read or -write characters, so the calling functions do not have to worry about -blocking data together in order to achieve efficiency. - -* Menu: - -* Creating an Lstream:: Creating an lstream object. -* Lstream Types:: Different sorts of things that are streamed. -* Lstream Functions:: Functions for working with lstreams. -* Lstream Methods:: Creating new lstream types. - - -File: internals.info, Node: Creating an Lstream, Next: Lstream Types, Up: Lstreams - -Creating an Lstream -=================== - - Lstreams come in different types, depending on what is being -interfaced to. Although the primitive for creating new lstreams is -`Lstream_new()', generally you do not call this directly. Instead, you -call some type-specific creation function, which creates the lstream -and initializes it as appropriate for the particular type. - - All lstream creation functions take a MODE argument, specifying what -mode the lstream should be opened as. This controls whether the -lstream is for input and output, and optionally whether data should be -blocked up in units of MULE characters. Note that some types of -lstreams can only be opened for input; others only for output; and -others can be opened either way. #### Richard Mlynarik thinks that -there should be a strict separation between input and output streams, -and he's probably right. - - MODE is a string, one of - -`"r"' - Open for reading. - -`"w"' - Open for writing. - -`"rc"' - Open for reading, but "read" never returns partial MULE characters. - -`"wc"' - Open for writing, but never writes partial MULE characters. - - -File: internals.info, Node: Lstream Types, Next: Lstream Functions, Prev: Creating an Lstream, Up: Lstreams - -Lstream Types -============= - -stdio - -filedesc - -lisp-string - -fixed-buffer - -resizing-buffer - -dynarr - -lisp-buffer - -print - -decoding - -encoding - - -File: internals.info, Node: Lstream Functions, Next: Lstream Methods, Prev: Lstream Types, Up: Lstreams - -Lstream Functions -================= - - - Function: Lstream * Lstream_new (Lstream_implementation *IMP, const - char *MODE) - Allocate and return a new Lstream. This function is not really - meant to be called directly; rather, each stream type should - provide its own stream creation function, which creates the stream - and does any other necessary creation stuff (e.g. opening a file). - - - Function: void Lstream_set_buffering (Lstream *LSTR, - Lstream_buffering BUFFERING, int BUFFERING_SIZE) - Change the buffering of a stream. See `lstream.h'. By default the - buffering is `STREAM_BLOCK_BUFFERED'. - - - Function: int Lstream_flush (Lstream *LSTR) - Flush out any pending unwritten data in the stream. Clear any - buffered input data. Returns 0 on success, -1 on error. - - - Macro: int Lstream_putc (Lstream *STREAM, int C) - Write out one byte to the stream. This is a macro and so it is - very efficient. The C argument is only evaluated once but the - STREAM argument is evaluated more than once. Returns 0 on - success, -1 on error. - - - Macro: int Lstream_getc (Lstream *STREAM) - Read one byte from the stream. This is a macro and so it is very - efficient. The STREAM argument is evaluated more than once. - Return value is -1 for EOF or error. - - - Macro: void Lstream_ungetc (Lstream *STREAM, int C) - Push one byte back onto the input queue. This will be the next - byte read from the stream. Any number of bytes can be pushed back - and will be read in the reverse order they were pushed back--most - recent first. (This is necessary for consistency--if there are a - number of bytes that have been unread and I read and unread a - byte, it needs to be the first to be read again.) This is a macro - and so it is very efficient. The C argument is only evaluated - once but the STREAM argument is evaluated more than once. - - - Function: int Lstream_fputc (Lstream *STREAM, int C) - - Function: int Lstream_fgetc (Lstream *STREAM) - - Function: void Lstream_fungetc (Lstream *STREAM, int C) - Function equivalents of the above macros. - - - Function: ssize_t Lstream_read (Lstream *STREAM, void *DATA, size_t - SIZE) - Read SIZE bytes of DATA from the stream. Return the number of - bytes read. 0 means EOF. -1 means an error occurred and no bytes - were read. - - - Function: ssize_t Lstream_write (Lstream *STREAM, void *DATA, size_t - SIZE) - Write SIZE bytes of DATA to the stream. Return the number of - bytes written. -1 means an error occurred and no bytes were - written. - - - Function: void Lstream_unread (Lstream *STREAM, void *DATA, size_t - SIZE) - Push back SIZE bytes of DATA onto the input queue. The next call - to `Lstream_read()' with the same size will read the same bytes - back. Note that this will be the case even if there is other - pending unread data. - - - Function: int Lstream_close (Lstream *STREAM) - Close the stream. All data will be flushed out. - - - Function: void Lstream_reopen (Lstream *STREAM) - Reopen a closed stream. This enables I/O on it again. This is not - meant to be called except from a wrapper routine that reinitializes - variables and such--the close routine may well have freed some - necessary storage structures, for example. - - - Function: void Lstream_rewind (Lstream *STREAM) - Rewind the stream to the beginning. - - -File: internals.info, Node: Lstream Methods, Prev: Lstream Functions, Up: Lstreams - -Lstream Methods -=============== - - - Lstream Method: ssize_t reader (Lstream *STREAM, unsigned char - *DATA, size_t SIZE) - Read some data from the stream's end and store it into DATA, which - can hold SIZE bytes. Return the number of bytes read. A return - value of 0 means no bytes can be read at this time. This may be - because of an EOF, or because there is a granularity greater than - one byte that the stream imposes on the returned data, and SIZE is - less than this granularity. (This will happen frequently for - streams that need to return whole characters, because - `Lstream_read()' calls the reader function repeatedly until it has - the number of bytes it wants or until 0 is returned.) The lstream - functions do not treat a 0 return as EOF or do anything special; - however, the calling function will interpret any 0 it gets back as - EOF. This will normally not happen unless the caller calls - `Lstream_read()' with a very small size. - - This function can be `NULL' if the stream is output-only. - - - Lstream Method: ssize_t writer (Lstream *STREAM, const unsigned char - *DATA, size_t SIZE) - Send some data to the stream's end. Data to be sent is in DATA - and is SIZE bytes. Return the number of bytes sent. This - function can send and return fewer bytes than is passed in; in that - case, the function will just be called again until there is no - data left or 0 is returned. A return value of 0 means that no - more data can be currently stored, but there is no error; the data - will be squirreled away until the writer can accept data. (This is - useful, e.g., if you're dealing with a non-blocking file - descriptor and are getting `EWOULDBLOCK' errors.) This function - can be `NULL' if the stream is input-only. - - - Lstream Method: int rewinder (Lstream *STREAM) - Rewind the stream. If this is `NULL', the stream is not seekable. - - - Lstream Method: int seekable_p (Lstream *STREAM) - Indicate whether this stream is seekable--i.e. it can be rewound. - This method is ignored if the stream does not have a rewind - method. If this method is not present, the result is determined - by whether a rewind method is present. - - - Lstream Method: int flusher (Lstream *STREAM) - Perform any additional operations necessary to flush the data in - this stream. - - - Lstream Method: int pseudo_closer (Lstream *STREAM) - - - Lstream Method: int closer (Lstream *STREAM) - Perform any additional operations necessary to close this stream - down. May be `NULL'. This function is called when - `Lstream_close()' is called or when the stream is - garbage-collected. When this function is called, all pending data - in the stream will already have been written out. - - - Lstream Method: Lisp_Object marker (Lisp_Object LSTREAM, void - (*MARKFUN) (Lisp_Object)) - Mark this object for garbage collection. Same semantics as a - standard `Lisp_Object' marker. This function can be `NULL'. - - -File: internals.info, Node: Consoles; Devices; Frames; Windows, Next: The Redisplay Mechanism, Prev: Lstreams, Up: Top - -Consoles; Devices; Frames; Windows -********************************** - -* Menu: - -* Introduction to Consoles; Devices; Frames; Windows:: -* Point:: -* Window Hierarchy:: -* The Window Object:: - - -File: internals.info, Node: Introduction to Consoles; Devices; Frames; Windows, Next: Point, Up: Consoles; Devices; Frames; Windows - -Introduction to Consoles; Devices; Frames; Windows -================================================== - - A window-system window that you see on the screen is called a -"frame" in Emacs terminology. Each frame is subdivided into one or -more non-overlapping panes, called (confusingly) "windows". Each -window displays the text of a buffer in it. (See above on Buffers.) Note -that buffers and windows are independent entities: Two or more windows -can be displaying the same buffer (potentially in different locations), -and a buffer can be displayed in no windows. - - A single display screen that contains one or more frames is called a -"display". Under most circumstances, there is only one display. -However, more than one display can exist, for example if you have a -"multi-headed" console, i.e. one with a single keyboard but multiple -displays. (Typically in such a situation, the various displays act like -one large display, in that the mouse is only in one of them at a time, -and moving the mouse off of one moves it into another.) In some cases, -the different displays will have different characteristics, e.g. one -color and one mono. - - XEmacs can display frames on multiple displays. It can even deal -simultaneously with frames on multiple keyboards (called "consoles" in -XEmacs terminology). Here is one case where this might be useful: You -are using XEmacs on your workstation at work, and leave it running. -Then you go home and dial in on a TTY line, and you can use the -already-running XEmacs process to display another frame on your local -TTY. - - Thus, there is a hierarchy console -> display -> frame -> window. -There is a separate Lisp object type for each of these four concepts. -Furthermore, there is logically a "selected console", "selected -display", "selected frame", and "selected window". Each of these -objects is distinguished in various ways, such as being the default -object for various functions that act on objects of that type. Note -that every containing object remembers the "selected" object among the -objects that it contains: e.g. not only is there a selected window, but -every frame remembers the last window in it that was selected, and -changing the selected frame causes the remembered window within it to -become the selected window. Similar relationships apply for consoles -to devices and devices to frames. - - -File: internals.info, Node: Point, Next: Window Hierarchy, Prev: Introduction to Consoles; Devices; Frames; Windows, Up: Consoles; Devices; Frames; Windows - -Point -===== - - Recall that every buffer has a current insertion position, called -"point". Now, two or more windows may be displaying the same buffer, -and the text cursor in the two windows (i.e. `point') can be in two -different places. You may ask, how can that be, since each buffer has -only one value of `point'? The answer is that each window also has a -value of `point' that is squirreled away in it. There is only one -selected window, and the value of "point" in that buffer corresponds to -that window. When the selected window is changed from one window to -another displaying the same buffer, the old value of `point' is stored -into the old window's "point" and the value of `point' from the new -window is retrieved and made the value of `point' in the buffer. This -means that `window-point' for the selected window is potentially -inaccurate, and if you want to retrieve the correct value of `point' -for a window, you must special-case on the selected window and retrieve -the buffer's point instead. This is related to why -`save-window-excursion' does not save the selected window's value of -`point'. - - -File: internals.info, Node: Window Hierarchy, Next: The Window Object, Prev: Point, Up: Consoles; Devices; Frames; Windows - -Window Hierarchy -================ - - If a frame contains multiple windows (panes), they are always created -by splitting an existing window along the horizontal or vertical axis. -Terminology is a bit confusing here: to "split a window horizontally" -means to create two side-by-side windows, i.e. to make a _vertical_ cut -in a window. Likewise, to "split a window vertically" means to create -two windows, one above the other, by making a _horizontal_ cut. - - If you split a window and then split again along the same axis, you -will end up with a number of panes all arranged along the same axis. -The precise way in which the splits were made should not be important, -and this is reflected internally. Internally, all windows are arranged -in a tree, consisting of two types of windows, "combination" windows -(which have children, and are covered completely by those children) and -"leaf" windows, which have no children and are visible. Every -combination window has two or more children, all arranged along the same -axis. There are (logically) two subtypes of windows, depending on -whether their children are horizontally or vertically arrayed. There is -always one root window, which is either a leaf window (if the frame -contains only one window) or a combination window (if the frame contains -more than one window). In the latter case, the root window will have -two or more children, either horizontally or vertically arrayed, and -each of those children will be either a leaf window or another -combination window. - - Here are some rules: - - 1. Horizontal combination windows can never have children that are - horizontal combination windows; same for vertical. - - 2. Only leaf windows can be split (obviously) and this splitting does - one of two things: (a) turns the leaf window into a combination - window and creates two new leaf children, or (b) turns the leaf - window into one of the two new leaves and creates the other leaf. - Rule (1) dictates which of these two outcomes happens. - - 3. Every combination window must have at least two children. - - 4. Leaf windows can never become combination windows. They can be - deleted, however. If this results in a violation of (3), the - parent combination window also gets deleted. - - 5. All functions that accept windows must be prepared to accept - combination windows, and do something sane (e.g. signal an error - if so). Combination windows _do_ escape to the Lisp level. - - 6. All windows have three fields governing their contents: these are - "hchild" (a list of horizontally-arrayed children), "vchild" (a - list of vertically-arrayed children), and "buffer" (the buffer - contained in a leaf window). Exactly one of these will be - non-`nil'. Remember that "horizontally-arrayed" means - "side-by-side" and "vertically-arrayed" means "one above the - other". - - 7. Leaf windows also have markers in their `start' (the first buffer - position displayed in the window) and `pointm' (the window's - stashed value of `point'--see above) fields, while combination - windows have `nil' in these fields. - - 8. The list of children for a window is threaded through the `next' - and `prev' fields of each child window. - - 9. *Deleted windows can be undeleted*. This happens as a result of - restoring a window configuration, and is unlike frames, displays, - and consoles, which, once deleted, can never be restored. - Deleting a window does nothing except set a special `dead' bit to - 1 and clear out the `next', `prev', `hchild', and `vchild' fields, - for GC purposes. - - 10. Most frames actually have two top-level windows--one for the - minibuffer and one (the "root") for everything else. The modeline - (if present) separates these two. The `next' field of the root - points to the minibuffer, and the `prev' field of the minibuffer - points to the root. The other `next' and `prev' fields are `nil', - and the frame points to both of these windows. Minibuffer-less - frames have no minibuffer window, and the `next' and `prev' of the - root window are `nil'. Minibuffer-only frames have no root - window, and the `next' of the minibuffer window is `nil' but the - `prev' points to itself. (#### This is an artifact that should be - fixed.) - - -File: internals.info, Node: The Window Object, Prev: Window Hierarchy, Up: Consoles; Devices; Frames; Windows - -The Window Object -================= - - Windows have the following accessible fields: - -`frame' - The frame that this window is on. - -`mini_p' - Non-`nil' if this window is a minibuffer window. - -`buffer' - The buffer that the window is displaying. This may change often - during the life of the window. - -`dedicated' - Non-`nil' if this window is dedicated to its buffer. - -`pointm' - This is the value of point in the current buffer when this window - is selected; when it is not selected, it retains its previous - value. - -`start' - The position in the buffer that is the first character to be - displayed in the window. - -`force_start' - If this flag is non-`nil', it says that the window has been - scrolled explicitly by the Lisp program. This affects what the - next redisplay does if point is off the screen: instead of - scrolling the window to show the text around point, it moves point - to a location that is on the screen. - -`last_modified' - The `modified' field of the window's buffer, as of the last time a - redisplay completed in this window. - -`last_point' - The buffer's value of point, as of the last time a redisplay - completed in this window. - -`left' - This is the left-hand edge of the window, measured in columns. - (The leftmost column on the screen is column 0.) - -`top' - This is the top edge of the window, measured in lines. (The top - line on the screen is line 0.) - -`height' - The height of the window, measured in lines. - -`width' - The width of the window, measured in columns. - -`next' - This is the window that is the next in the chain of siblings. It - is `nil' in a window that is the rightmost or bottommost of a - group of siblings. - -`prev' - This is the window that is the previous in the chain of siblings. - It is `nil' in a window that is the leftmost or topmost of a group - of siblings. - -`parent' - Internally, XEmacs arranges windows in a tree; each group of - siblings has a parent window whose area includes all the siblings. - This field points to a window's parent. - - Parent windows do not display buffers, and play little role in - display except to shape their child windows. Emacs Lisp programs - usually have no access to the parent windows; they operate on the - windows at the leaves of the tree, which actually display buffers. - -`hscroll' - This is the number of columns that the display in the window is - scrolled horizontally to the left. Normally, this is 0. - -`use_time' - This is the last time that the window was selected. The function - `get-lru-window' uses this field. - -`display_table' - The window's display table, or `nil' if none is specified for it. - -`update_mode_line' - Non-`nil' means this window's mode line needs to be updated. - -`base_line_number' - The line number of a certain position in the buffer, or `nil'. - This is used for displaying the line number of point in the mode - line. - -`base_line_pos' - The position in the buffer for which the line number is known, or - `nil' meaning none is known. - -`region_showing' - If the region (or part of it) is highlighted in this window, this - field holds the mark position that made one end of that region. - Otherwise, this field is `nil'. - - -File: internals.info, Node: The Redisplay Mechanism, Next: Extents, Prev: Consoles; Devices; Frames; Windows, Up: Top - -The Redisplay Mechanism -*********************** - - The redisplay mechanism is one of the most complicated sections of -XEmacs, especially from a conceptual standpoint. This is doubly so -because, unlike for the basic aspects of the Lisp interpreter, the -computer science theories of how to efficiently handle redisplay are not -well-developed. - - When working with the redisplay mechanism, remember the Golden Rules -of Redisplay: - - 1. It Is Better To Be Correct Than Fast. - - 2. Thou Shalt Not Run Elisp From Within Redisplay. - - 3. It Is Better To Be Fast Than Not To Be. - -* Menu: - -* Critical Redisplay Sections:: -* Line Start Cache:: -* Redisplay Piece by Piece:: - - -File: internals.info, Node: Critical Redisplay Sections, Next: Line Start Cache, Up: The Redisplay Mechanism - -Critical Redisplay Sections -=========================== - - Within this section, we are defenseless and assume that the -following cannot happen: - - 1. garbage collection - - 2. Lisp code evaluation - - 3. frame size changes - - We ensure (3) by calling `hold_frame_size_changes()', which will -cause any pending frame size changes to get put on hold till after the -end of the critical section. (1) follows automatically if (2) is met. -#### Unfortunately, there are some places where Lisp code can be called -within this section. We need to remove them. - - If `Fsignal()' is called during this critical section, we will -`abort()'. - - If garbage collection is called during this critical section, we -simply return. #### We should abort instead. - - #### If a frame-size change does occur we should probably actually -be preempting redisplay. - - -File: internals.info, Node: Line Start Cache, Next: Redisplay Piece by Piece, Prev: Critical Redisplay Sections, Up: The Redisplay Mechanism - -Line Start Cache -================ - - The traditional scrolling code in Emacs breaks in a variable height -world. It depends on the key assumption that the number of lines that -can be displayed at any given time is fixed. This led to a complete -separation of the scrolling code from the redisplay code. In order to -fully support variable height lines, the scrolling code must actually be -tightly integrated with redisplay. Only redisplay can determine how -many lines will be displayed on a screen for any given starting point. - - What is ideally wanted is a complete list of the starting buffer -position for every possible display line of a buffer along with the -height of that display line. Maintaining such a full list would be very -expensive. We settle for having it include information for all areas -which we happen to generate anyhow (i.e. the region currently being -displayed) and for those areas we need to work with. - - In order to ensure that the cache accurately represents what -redisplay would actually show, it is necessary to invalidate it in many -situations. If the buffer changes, the starting positions may no longer -be correct. If a face or an extent has changed then the line heights -may have altered. These events happen frequently enough that the cache -can end up being constantly disabled. With this potentially constant -invalidation when is the cache ever useful? - - Even if the cache is invalidated before every single usage, it is -necessary. Scrolling often requires knowledge about display lines which -are actually above or below the visible region. The cache provides a -convenient light-weight method of storing this information for multiple -display regions. This knowledge is necessary for the scrolling code to -always obey the First Golden Rule of Redisplay. - - If the cache already contains all of the information that the -scrolling routines happen to need so that it doesn't have to go -generate it, then we are able to obey the Third Golden Rule of -Redisplay. The first thing we do to help out the cache is to always -add the displayed region. This region had to be generated anyway, so -the cache ends up getting the information basically for free. In those -cases where a user is simply scrolling around viewing a buffer there is -a high probability that this is sufficient to always provide the needed -information. The second thing we can do is be smart about invalidating -the cache. - - TODO--Be smart about invalidating the cache. Potential places: - - * Insertions at end-of-line which don't cause line-wraps do not - alter the starting positions of any display lines. These types of - buffer modifications should not invalidate the cache. This is - actually a large optimization for redisplay speed as well. - - * Buffer modifications frequently only affect the display of lines - at and below where they occur. In these situations we should only - invalidate the part of the cache starting at where the - modification occurs. - - In case you're wondering, the Second Golden Rule of Redisplay is not -applicable. - - -File: internals.info, Node: Redisplay Piece by Piece, Prev: Line Start Cache, Up: The Redisplay Mechanism - -Redisplay Piece by Piece -======================== - - As you can begin to see redisplay is complex and also not well -documented. Chuck no longer works on XEmacs so this section is my take -on the workings of redisplay. - - Redisplay happens in three phases: - - 1. Determine desired display in area that needs redisplay. - Implemented by `redisplay.c' - - 2. Compare desired display with current display Implemented by - `redisplay-output.c' - - 3. Output changes Implemented by `redisplay-output.c', - `redisplay-x.c', `redisplay-msw.c' and `redisplay-tty.c' - - Steps 1 and 2 are device-independent and relatively complex. Step 3 -is mostly device-dependent. - - Determining the desired display - - Display attributes are stored in `display_line' structures. Each -`display_line' consists of a set of `display_block''s and each -`display_block' contains a number of `rune''s. Generally dynarr's of -`display_line''s are held by each window representing the current -display and the desired display. - - The `display_line' structures are tightly tied to buffers which -presents a problem for redisplay as this connection is bogus for the -modeline. Hence the `display_line' generation routines are duplicated -for generating the modeline. This means that the modeline display code -has many bugs that the standard redisplay code does not. - - The guts of `display_line' generation are in `create_text_block', -which creates a single display line for the desired locale. This -incrementally parses the characters on the current line and generates -redisplay structures for each. - - Gutter redisplay is different. Because the data to display is stored -in a string we cannot use `create_text_block'. Instead we use -`create_text_string_block' which performs the same function as -`create_text_block' but for strings. Many of the complexities of -`create_text_block' to do with cursor handling and selective display -have been removed. - - -File: internals.info, Node: Extents, Next: Faces, Prev: The Redisplay Mechanism, Up: Top - -Extents -******* - -* Menu: - -* Introduction to Extents:: Extents are ranges over text, with properties. -* Extent Ordering:: How extents are ordered internally. -* Format of the Extent Info:: The extent information in a buffer or string. -* Zero-Length Extents:: A weird special case. -* Mathematics of Extent Ordering:: A rigorous foundation. -* Extent Fragments:: Cached information useful for redisplay. - - -File: internals.info, Node: Introduction to Extents, Next: Extent Ordering, Up: Extents - -Introduction to Extents -======================= - - Extents are regions over a buffer, with a start and an end position -denoting the region of the buffer included in the extent. In addition, -either end can be closed or open, meaning that the endpoint is or is -not logically included in the extent. Insertion of a character at a -closed endpoint causes the character to go inside the extent; insertion -at an open endpoint causes the character to go outside. - - Extent endpoints are stored using memory indices (see `insdel.c'), -to minimize the amount of adjusting that needs to be done when -characters are inserted or deleted. - - (Formerly, extent endpoints at the gap could be either before or -after the gap, depending on the open/closedness of the endpoint. The -intent of this was to make it so that insertions would automatically go -inside or out of extents as necessary with no further work needing to -be done. It didn't work out that way, however, and just ended up -complexifying and buggifying all the rest of the code.) - - -File: internals.info, Node: Extent Ordering, Next: Format of the Extent Info, Prev: Introduction to Extents, Up: Extents - -Extent Ordering -=============== - - Extents are compared using memory indices. There are two orderings -for extents and both orders are kept current at all times. The normal -or "display" order is as follows: - - Extent A is ``less than'' extent B, - that is, earlier in the display order, - if: A-start < B-start, - or if: A-start = B-start, and A-end > B-end - - So if two extents begin at the same position, the larger of them is -the earlier one in the display order (`EXTENT_LESS' is true). - - For the e-order, the same thing holds: - - Extent A is ``less than'' extent B in e-order, - that is, later in the buffer, - if: A-end < B-end, - or if: A-end = B-end, and A-start > B-start - - So if two extents end at the same position, the smaller of them is -the earlier one in the e-order (`EXTENT_E_LESS' is true). - - The display order and the e-order are complementary orders: any -theorem about the display order also applies to the e-order if you swap -all occurrences of "display order" and "e-order", "less than" and -"greater than", and "extent start" and "extent end". - - -File: internals.info, Node: Format of the Extent Info, Next: Zero-Length Extents, Prev: Extent Ordering, Up: Extents - -Format of the Extent Info -========================= - - An extent-info structure consists of a list of the buffer or string's -extents and a "stack of extents" that lists all of the extents over a -particular position. The stack-of-extents info is used for -optimization purposes--it basically caches some info that might be -expensive to compute. Certain otherwise hard computations are easy -given the stack of extents over a particular position, and if the stack -of extents over a nearby position is known (because it was calculated -at some prior point in time), it's easy to move the stack of extents to -the proper position. - - Given that the stack of extents is an optimization, and given that -it requires memory, a string's stack of extents is wiped out each time -a garbage collection occurs. Therefore, any time you retrieve the -stack of extents, it might not be there. If you need it to be there, -use the `_force' version. - - Similarly, a string may or may not have an extent_info structure. -(Generally it won't if there haven't been any extents added to the -string.) So use the `_force' version if you need the extent_info -structure to be there. - - A list of extents is maintained as a double gap array: one gap array -is ordered by start index (the "display order") and the other is -ordered by end index (the "e-order"). Note that positions in an extent -list should logically be conceived of as referring _to_ a particular -extent (as is the norm in programs) rather than sitting between two -extents. Note also that callers of these functions should not be aware -of the fact that the extent list is implemented as an array, except for -the fact that positions are integers (this should be generalized to -handle integers and linked list equally well). - - -File: internals.info, Node: Zero-Length Extents, Next: Mathematics of Extent Ordering, Prev: Format of the Extent Info, Up: Extents - -Zero-Length Extents -=================== - - Extents can be zero-length, and will end up that way if their -endpoints are explicitly set that way or if their detachable property -is `nil' and all the text in the extent is deleted. (The exception is -open-open zero-length extents, which are barred from existing because -there is no sensible way to define their properties. Deletion of the -text in an open-open extent causes it to be converted into a closed-open -extent.) Zero-length extents are primarily used to represent -annotations, and behave as follows: - - 1. Insertion at the position of a zero-length extent expands the - extent if both endpoints are closed; goes after the extent if it - is closed-open; and goes before the extent if it is open-closed. - - 2. Deletion of a character on a side of a zero-length extent whose - corresponding endpoint is closed causes the extent to be detached - if it is detachable; if the extent is not detachable or the - corresponding endpoint is open, the extent remains in the buffer, - moving as necessary. - - Note that closed-open, non-detachable zero-length extents behave -exactly like markers and that open-closed, non-detachable zero-length -extents behave like the "point-type" marker in Mule. - - -File: internals.info, Node: Mathematics of Extent Ordering, Next: Extent Fragments, Prev: Zero-Length Extents, Up: Extents - -Mathematics of Extent Ordering -============================== - - The extents in a buffer are ordered by "display order" because that -is that order that the redisplay mechanism needs to process them in. -The e-order is an auxiliary ordering used to facilitate operations over -extents. The operations that can be performed on the ordered list of -extents in a buffer are - - 1. Locate where an extent would go if inserted into the list. - - 2. Insert an extent into the list. - - 3. Remove an extent from the list. - - 4. Map over all the extents that overlap a range. - - (4) requires being able to determine the first and last extents that -overlap a range. - - NOTE: "overlap" is used as follows: - - * two ranges overlap if they have at least one point in common. - Whether the endpoints are open or closed makes a difference here. - - * a point overlaps a range if the point is contained within the - range; this is equivalent to treating a point P as the range [P, - P]. - - * In the case of an _extent_ overlapping a point or range, the extent - is normally treated as having closed endpoints. This applies - consistently in the discussion of stacks of extents and such below. - Note that this definition of overlap is not necessarily consistent - with the extents that `map-extents' maps over, since `map-extents' - sometimes pays attention to whether the endpoints of an extents - are open or closed. But for our purposes, it greatly simplifies - things to treat all extents as having closed endpoints. - - First, define >, <, <=, etc. as applied to extents to mean -comparison according to the display order. Comparison between an -extent E and an index I means comparison between E and the range [I, I]. - - Also define e>, e<, e<=, etc. to mean comparison according to the -e-order. - - For any range R, define R(0) to be the starting index of the range -and R(1) to be the ending index of the range. - - For any extent E, define E(next) to be the extent directly following -E, and E(prev) to be the extent directly preceding E. Assume E(next) -and E(prev) can be determined from E in constant time. (This is -because we store the extent list as a doubly linked list.) - - Similarly, define E(e-next) and E(e-prev) to be the extents directly -following and preceding E in the e-order. - - Now: - - Let R be a range. Let F be the first extent overlapping R. Let L -be the last extent overlapping R. - - Theorem 1: R(1) lies between L and L(next), i.e. L <= R(1) < L(next). - - This follows easily from the definition of display order. The basic -reason that this theorem applies is that the display order sorts by -increasing starting index. - - Therefore, we can determine L just by looking at where we would -insert R(1) into the list, and if we know F and are moving forward over -extents, we can easily determine when we've hit L by comparing the -extent we're at to R(1). - - Theorem 2: F(e-prev) e< [1, R(0)] e<= F. - - This is the analog of Theorem 1, and applies because the e-order -sorts by increasing ending index. - - Therefore, F can be found in the same amount of time as operation -(1), i.e. the time that it takes to locate where an extent would go if -inserted into the e-order list. - - If the lists were stored as balanced binary trees, then operation (1) -would take logarithmic time, which is usually quite fast. However, -currently they're stored as simple doubly-linked lists, and instead we -do some caching to try to speed things up. - - Define a "stack of extents" (or "SOE") as the set of extents -(ordered in the display order) that overlap an index I, together with -the SOE's "previous" extent, which is an extent that precedes I in the -e-order. (Hopefully there will not be very many extents between I and -the previous extent.) - - Now: - - Let I be an index, let S be the stack of extents on I, let F be the -first extent in S, and let P be S's previous extent. - - Theorem 3: The first extent in S is the first extent that overlaps -any range [I, J]. - - Proof: Any extent that overlaps [I, J] but does not include I must -have a start index > I, and thus be greater than any extent in S. - - Therefore, finding the first extent that overlaps a range R is the -same as finding the first extent that overlaps R(0). - - Theorem 4: Let I2 be an index such that I2 > I, and let F2 be the -first extent that overlaps I2. Then, either F2 is in S or F2 is -greater than any extent in S. - - Proof: If F2 does not include I then its start index is greater than -I and thus it is greater than any extent in S, including F. Otherwise, -F2 includes I and thus is in S, and thus F2 >= F. - - -File: internals.info, Node: Extent Fragments, Prev: Mathematics of Extent Ordering, Up: Extents - -Extent Fragments -================ - - Imagine that the buffer is divided up into contiguous, -non-overlapping "runs" of text such that no extent starts or ends -within a run (extents that abut the run don't count). - - An extent fragment is a structure that holds data about the run that -contains a particular buffer position (if the buffer position is at the -junction of two runs, the run after the position is used)--the -beginning and end of the run, a list of all of the extents in that run, -the "merged face" that results from merging all of the faces -corresponding to those extents, the begin and end glyphs at the -beginning of the run, etc. This is the information that redisplay needs -in order to display this run. - - Extent fragments have to be very quick to update to a new buffer -position when moving linearly through the buffer. They rely on the -stack-of-extents code, which does the heavy-duty algorithmic work of -determining which extents overly a particular position. - - -File: internals.info, Node: Faces, Next: Glyphs, Prev: Extents, Up: Top - -Faces -***** - - Not yet documented. - diff -u -r -N xemacs-21.4.14/info/internals.info-9 xemacs-21.4.15/info/internals.info-9 --- xemacs-21.4.14/info/internals.info-9 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/internals.info-9 1969-12-31 19:00:00.000000000 -0500 @@ -1,880 +0,0 @@ -This is ../info/internals.info, produced by makeinfo version 4.5 from -internals/internals.texi. - -INFO-DIR-SECTION XEmacs Editor -START-INFO-DIR-ENTRY -* Internals: (internals). XEmacs Internals Manual. -END-INFO-DIR-ENTRY - - Copyright (C) 1992 - 1996 Ben Wing. Copyright (C) 1996, 1997 Sun -Microsystems. Copyright (C) 1994 - 1998 Free Software Foundation. -Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. - - 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 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. - - -File: internals.info, Node: Glyphs, Next: Specifiers, Prev: Faces, Up: Top - -Glyphs -****** - - Glyphs are graphical elements that can be displayed in XEmacs -buffers or gutters. We use the term graphical element here in the -broadest possible sense since glyphs can be as mundane as text or as -arcane as a native tab widget. - - In XEmacs, glyphs represent the uninstantiated state of graphical -elements, i.e. they hold all the information necessary to produce an -image on-screen but the image need not exist at this stage, and multiple -screen images can be instantiated from a single glyph. - - Glyphs are lazily instantiated by calling one of the glyph -functions. This usually occurs within redisplay when `Fglyph_height' is -called. Instantiation causes an image-instance to be created and -cached. This cache is on a per-device basis for all glyphs except -widget-glyphs, and on a per-window basis for widgets-glyphs. The -caching is done by `image_instantiate' and is necessary because it is -generally possible to display an image-instance in multiple domains. -For instance if we create a Pixmap, we can actually display this on -multiple windows - even though we only need a single Pixmap instance to -do this. If caching wasn't done then it would be necessary to create -image-instances for every displayable occurrence of a glyph - and every -usage - and this would be extremely memory and cpu intensive. - - Widget-glyphs (a.k.a native widgets) are not cached in this way. -This is because widget-glyph image-instances on screen are toolkit -windows, and thus cannot be reused in multiple XEmacs domains. Thus -widget-glyphs are cached on an XEmacs window basis. - - Any action on a glyph first consults the cache before actually -instantiating a widget. - -Glyph Instantiation -=================== - - Glyph instantiation is a hairy topic and requires some explanation. -The guts of glyph instantiation is contained within -`image_instantiate'. A glyph contains an image which is a specifier. -When a glyph function - for instance `Fglyph_height' - asks for a -property of the glyph that can only be determined from its instantiated -state, then the glyph image is instantiated and an image instance -created. The instantiation process is governed by the specifier code -and goes through a series of steps: - - * Validation. Instantiation of image instances happens dynamically - - often within the guts of redisplay. Thus it is often not feasible - to catch instantiator errors at instantiation time. Instead the - instantiator is validated at the time it is added to the image - specifier. This function is defined by `image_validate' and at a - simple level validates keyword value pairs. - - * Duplication. The specifier code by default takes a copy of the - instantiator. This is reasonable for most specifiers but in the - case of widget-glyphs can be problematic, since some of the - properties in the instantiator - for instance callbacks - could - cause infinite recursion in the copying process. Thus the image - code defines a function - `image_copy_instantiator' - which will - selectively copy values. This is controlled by the way that a - keyword is defined either using `IIFORMAT_VALID_KEYWORD' or - `IIFORMAT_VALID_NONCOPY_KEYWORD'. Note that the image caching and - redisplay code relies on instantiator copying to ensure that - current and new instantiators are actually different rather than - referring to the same thing. - - * Normalization. Once the instantiator has been copied it must be - converted into a form that is viable at instantiation time. This - can involve no changes at all, but typically involves things like - converting file names to the actual data. This function is defined - by `image_going_to_add' and `normalize_image_instantiator'. - - * Instantiation. When an image instance is actually required for - display it is instantiated using `image_instantiate'. This - involves calling instantiate methods that are specific to the type - of image being instantiated. - - The final instantiation phase also involves a number of steps. In -order to understand these we need to describe a number of concepts. - - An image is instantiated in a "domain", where a domain can be any -one of a device, frame, window or image-instance. The domain gives the -image-instance context and identity and properties that affect the -appearance of the image-instance may be different for the same glyph -instantiated in different domains. An example is the face used to -display the image-instance. - - Although an image is instantiated in a particular domain the -instantiation domain is not necessarily the domain in which the -image-instance is cached. For example a pixmap can be instantiated in a -window be actually be cached on a per-device basis. The domain in which -the image-instance is actually cached is called the "governing-domain". -A governing-domain is currently either a device or a window. -Widget-glyphs and text-glyphs have a window as a governing-domain, all -other image-instances have a device as the governing-domain. The -governing domain for an image-instance is determined using the -governing_domain image-instance method. - -Widget-Glyphs -============= - -Widget-Glyphs in the MS-Windows Environment -=========================================== - - To Do - -Widget-Glyphs in the X Environment -================================== - - Widget-glyphs under X make heavy use of lwlib (*note Lucid Widget -Library::) for manipulating the native toolkit objects. This is -primarily so that different toolkits can be supported for -widget-glyphs, just as they are supported for features such as menubars -etc. - - Lwlib is extremely poorly documented and quite hairy so here is my -understanding of what goes on. - - Lwlib maintains a set of widget_instances which mirror the -hierarchical state of Xt widgets. I think this is so that widgets can -be updated and manipulated generically by the lwlib library. For -instance update_one_widget_instance can cope with multiple types of -widget and multiple types of toolkit. Each element in the widget -hierarchy is updated from its corresponding widget_instance by walking -the widget_instance tree recursively. - - This has desirable properties such as lw_modify_all_widgets which is -called from `glyphs-x.c' and updates all the properties of a widget -without having to know what the widget is or what toolkit it is from. -Unfortunately this also has hairy properties such as making the lwlib -code quite complex. And of course lwlib has to know at some level what -the widget is and how to set its properties. - - -File: internals.info, Node: Specifiers, Next: Menus, Prev: Glyphs, Up: Top - -Specifiers -********** - - Not yet documented. - - -File: internals.info, Node: Menus, Next: Subprocesses, Prev: Specifiers, Up: Top - -Menus -***** - - A menu is set by setting the value of the variable `current-menubar' -(which may be buffer-local) and then calling `set-menubar-dirty-flag' -to signal a change. This will cause the menu to be redrawn at the next -redisplay. The format of the data in `current-menubar' is described in -`menubar.c'. - - Internally the data in current-menubar is parsed into a tree of -`widget_value's' (defined in `lwlib.h'); this is accomplished by the -recursive function `menu_item_descriptor_to_widget_value()', called by -`compute_menubar_data()'. Such a tree is deallocated using -`free_widget_value()'. - - `update_screen_menubars()' is one of the external entry points. -This checks to see, for each screen, if that screen's menubar needs to -be updated. This is the case if - - 1. `set-menubar-dirty-flag' was called since the last redisplay. - (This function sets the C variable menubar_has_changed.) - - 2. The buffer displayed in the screen has changed. - - 3. The screen has no menubar currently displayed. - - `set_screen_menubar()' is called for each such screen. This -function calls `compute_menubar_data()' to create the tree of -widget_value's, then calls `lw_create_widget()', -`lw_modify_all_widgets()', and/or `lw_destroy_all_widgets()' to create -the X-Toolkit widget associated with the menu. - - `update_psheets()', the other external entry point, actually changes -the menus being displayed. It uses the widgets fixed by -`update_screen_menubars()' and calls various X functions to ensure that -the menus are displayed properly. - - The menubar widget is set up so that `pre_activate_callback()' is -called when the menu is first selected (i.e. mouse button goes down), -and `menubar_selection_callback()' is called when an item is selected. -`pre_activate_callback()' calls the function in activate-menubar-hook, -which can change the menubar (this is described in `menubar.c'). If -the menubar is changed, `set_screen_menubars()' is called. -`menubar_selection_callback()' enqueues a menu event, putting in it a -function to call (either `eval' or `call-interactively') and its -argument, which is the callback function or form given in the menu's -description. - - -File: internals.info, Node: Subprocesses, Next: Interface to the X Window System, Prev: Menus, Up: Top - -Subprocesses -************ - - The fields of a process are: - -`name' - A string, the name of the process. - -`command' - A list containing the command arguments that were used to start - this process. - -`filter' - A function used to accept output from the process instead of a - buffer, or `nil'. - -`sentinel' - A function called whenever the process receives a signal, or `nil'. - -`buffer' - The associated buffer of the process. - -`pid' - An integer, the Unix process ID. - -`childp' - A flag, non-`nil' if this is really a child process. It is `nil' - for a network connection. - -`mark' - A marker indicating the position of the end of the last output - from this process inserted into the buffer. This is often but not - always the end of the buffer. - -`kill_without_query' - If this is non-`nil', killing XEmacs while this process is still - running does not ask for confirmation about killing the process. - -`raw_status_low' -`raw_status_high' - These two fields record 16 bits each of the process status - returned by the `wait' system call. - -`status' - The process status, as `process-status' should return it. - -`tick' -`update_tick' - If these two fields are not equal, a change in the status of the - process needs to be reported, either by running the sentinel or by - inserting a message in the process buffer. - -`pty_flag' - Non-`nil' if communication with the subprocess uses a PTY; `nil' - if it uses a pipe. - -`infd' - The file descriptor for input from the process. - -`outfd' - The file descriptor for output to the process. - -`subtty' - The file descriptor for the terminal that the subprocess is using. - (On some systems, there is no need to record this, so the value is - `-1'.) - -`tty_name' - The name of the terminal that the subprocess is using, or `nil' if - it is using pipes. - - -File: internals.info, Node: Interface to the X Window System, Next: Index, Prev: Subprocesses, Up: Top - -Interface to the X Window System -******************************** - - Mostly undocumented. - -* Menu: - -* Lucid Widget Library:: An interface to various widget sets. - - -File: internals.info, Node: Lucid Widget Library, Up: Interface to the X Window System - -Lucid Widget Library -==================== - - Lwlib is extremely poorly documented and quite hairy. The author(s) -blame that on X, Xt, and Motif, with some justice, but also sufficient -hypocrisy to avoid drawing the obvious conclusion about their own work. - - The Lucid Widget Library is composed of two more or less independent -pieces. The first, as the name suggests, is a set of widgets. These -widgets are intended to resemble and improve on widgets provided in the -Motif toolkit but not in the Athena widgets, including menubars and -scrollbars. Recent additions by Andy Piper integrate some "modern" -widgets by Edward Falk, including checkboxes, radio buttons, progress -gauges, and index tab controls (aka notebooks). - - The second piece of the Lucid widget library is a generic interface -to several toolkits for X (including Xt, the Athena widget set, and -Motif, as well as the Lucid widgets themselves) so that core XEmacs -code need not know which widget set has been used to build the -graphical user interface. - -* Menu: - -* Generic Widget Interface:: The lwlib generic widget interface. -* Scrollbars:: -* Menubars:: -* Checkboxes and Radio Buttons:: -* Progress Bars:: -* Tab Controls:: - - -File: internals.info, Node: Generic Widget Interface, Next: Scrollbars, Up: Lucid Widget Library - -Generic Widget Interface ------------------------- - - In general in any toolkit a widget may be a composite object. In Xt, -all widgets have an X window that they manage, but typically a complex -widget will have widget children, each of which manages a subwindow of -the parent widget's X window. These children may themselves be -composite widgets. Thus a widget is actually a tree or hierarchy of -widgets. - - For each toolkit widget, lwlib maintains a tree of `widget_values' -which mirror the hierarchical state of Xt widgets (including Motif, -Athena, 3D Athena, and Falk's widget sets). Each `widget_value' has -`contents' member, which points to the head of a linked list of its -children. The linked list of siblings is chained through the `next' -member of `widget_value'. - - +-----------+ - | composite | - +-----------+ - | - | contents - V - +-------+ next +-------+ next +-------+ - | child |----->| child |----->| child | - +-------+ +-------+ +-------+ - | - | contents - V - +-------------+ next +-------------+ - | grand child |----->| grand child | - +-------------+ +-------------+ - - The `widget_value' hierarchy of a composite widget with two simple - children and one composite child. - - The `widget_instance' structure maintains the inverse view of the -tree. As for the `widget_value', siblings are chained through the -`next' member. However, rather than naming children, the -`widget_instance' tree links to parents. - - +-----------+ - | composite | - +-----------+ - A - | parent - | - +-------+ next +-------+ next +-------+ - | child |----->| child |----->| child | - +-------+ +-------+ +-------+ - A - | parent - | - +-------------+ next +-------------+ - | grand child |----->| grand child | - +-------------+ +-------------+ - - The `widget_value' hierarchy of a composite widget with two simple - children and one composite child. - - This permits widgets derived from different toolkits to be updated -and manipulated generically by the lwlib library. For instance -`update_one_widget_instance' can cope with multiple types of widget and -multiple types of toolkit. Each element in the widget hierarchy is -updated from its corresponding `widget_value' by walking the -`widget_value' tree. This has desirable properties. For example, -`lw_modify_all_widgets' is called from `glyphs-x.c' and updates all the -properties of a widget without having to know what the widget is or -what toolkit it is from. Unfortunately this also has its hairy -properties; the lwlib code quite complex. And of course lwlib has to -know at some level what the widget is and how to set its properties. - - The `widget_instance' structure also contains a pointer to the root -of its tree. Widget instances are further confi - - -File: internals.info, Node: Scrollbars, Next: Menubars, Prev: Generic Widget Interface, Up: Lucid Widget Library - -Scrollbars ----------- - - -File: internals.info, Node: Menubars, Next: Checkboxes and Radio Buttons, Prev: Scrollbars, Up: Lucid Widget Library - -Menubars --------- - - -File: internals.info, Node: Checkboxes and Radio Buttons, Next: Progress Bars, Prev: Menubars, Up: Lucid Widget Library - -Checkboxes and Radio Buttons ----------------------------- - - -File: internals.info, Node: Progress Bars, Next: Tab Controls, Prev: Checkboxes and Radio Buttons, Up: Lucid Widget Library - -Progress Bars -------------- - - -File: internals.info, Node: Tab Controls, Prev: Progress Bars, Up: Lucid Widget Library - -Tab Controls ------------- - - -File: internals.info, Node: Index, Prev: Interface to the X Window System, Up: Top - -Index -***** - -* Menu: - -* allocation from frob blocks: Allocation from Frob Blocks. -* allocation of objects in XEmacs Lisp: Allocation of Objects in XEmacs Lisp. -* allocation, introduction to: Introduction to Allocation. -* allocation, low-level: Low-level allocation. -* Amdahl Corporation: XEmacs. -* Andreessen, Marc: XEmacs. -* asynchronous subprocesses: Modules for Interfacing with the Operating System. -* bars, progress: Progress Bars. -* Baur, Steve: XEmacs. -* Benson, Eric: Lucid Emacs. -* binding; the specbinding stack; unwind-protects, dynamic: Dynamic Binding; The specbinding Stack; Unwind-Protects. -* bindings, evaluation; stack frames;: Evaluation; Stack Frames; Bindings. -* bit vector: Bit Vector. -* bridge, playing: XEmacs From the Outside. -* Buchholz, Martin: XEmacs. -* Bufbyte: Character-Related Data Types. -* Bufbytes and Emchars: Bufbytes and Emchars. -* buffer lists: Buffer Lists. -* buffer object, the: The Buffer Object. -* buffer, the text in a: The Text in a Buffer. -* buffers and textual representation: Buffers and Textual Representation. -* buffers, introduction to: Introduction to Buffers. -* Bufpos: Character-Related Data Types. -* building, XEmacs from the perspective of: XEmacs From the Perspective of Building. -* buttons, checkboxes and radio: Checkboxes and Radio Buttons. -* byte positions, working with character and: Working With Character and Byte Positions. -* Bytecount: Character-Related Data Types. -* bytecount_to_charcount: Working With Character and Byte Positions. -* Bytind: Character-Related Data Types. -* C code, rules when writing new: Rules When Writing New C Code. -* C vs. Lisp: The Lisp Language. -* callback routines, the event stream: The Event Stream Callback Routines. -* caller-protects (GCPRO rule): Writing Lisp Primitives. -* case table: Modules for Other Aspects of the Lisp Interpreter and Object System. -* catch and throw: Catch and Throw. -* CCL: CCL. -* character and byte positions, working with: Working With Character and Byte Positions. -* character encoding, internal: Internal Character Encoding. -* character sets: Character Sets. -* character sets and encodings, Mule: MULE Character Sets and Encodings. -* character-related data types: Character-Related Data Types. -* characters, integers and: Integers and Characters. -* Charcount: Character-Related Data Types. -* charcount_to_bytecount: Working With Character and Byte Positions. -* charptr_emchar: Working With Character and Byte Positions. -* charptr_n_addr: Working With Character and Byte Positions. -* checkboxes and radio buttons: Checkboxes and Radio Buttons. -* closer: Lstream Methods. -* closure: The XEmacs Object System (Abstractly Speaking). -* code, an example of Mule-aware: An Example of Mule-Aware Code. -* code, general guidelines for writing Mule-aware: General Guidelines for Writing Mule-Aware Code. -* code, rules when writing new C: Rules When Writing New C Code. -* coding for Mule: Coding for Mule. -* coding rules, general: General Coding Rules. -* command builder, dispatching events; the: Dispatching Events; The Command Builder. -* comments, writing good: Writing Good Comments. -* Common Lisp: The Lisp Language. -* compact_string_chars: compact_string_chars. -* compiled function: Compiled Function. -* compiler, the Lisp reader and: The Lisp Reader and Compiler. -* cons: Cons. -* conservative garbage collection: GCPROing. -* consoles; devices; frames; windows: Consoles; Devices; Frames; Windows. -* consoles; devices; frames; windows, introduction to: Introduction to Consoles; Devices; Frames; Windows. -* control flow modules, editor-level: Editor-Level Control Flow Modules. -* conversion to and from external data: Conversion to and from External Data. -* converting events: Converting Events. -* copy-on-write: General Coding Rules. -* creating Lisp object types: Techniques for XEmacs Developers. -* critical redisplay sections: Critical Redisplay Sections. -* data dumping: Data dumping. -* data types, character-related: Character-Related Data Types. -* DEC_CHARPTR: Working With Character and Byte Positions. -* developers, techniques for XEmacs: Techniques for XEmacs Developers. -* devices; frames; windows, consoles;: Consoles; Devices; Frames; Windows. -* devices; frames; windows, introduction to consoles;: Introduction to Consoles; Devices; Frames; Windows. -* Devin, Matthieu: Lucid Emacs. -* dispatching events; the command builder: Dispatching Events; The Command Builder. -* display order of extents: Mathematics of Extent Ordering. -* display-related Lisp objects, modules for other: Modules for other Display-Related Lisp Objects. -* displayable Lisp objects, modules for the basic: Modules for the Basic Displayable Lisp Objects. -* dumping: Dumping. -* dumping address allocation: Address allocation. -* dumping and its justification, what is: Dumping. -* dumping data descriptions: Data descriptions. -* dumping object inventory: Object inventory. -* dumping overview: Overview. -* dumping phase: Dumping phase. -* dumping, data: Data dumping. -* dumping, file loading: Reloading phase. -* dumping, object relocation: Reloading phase. -* dumping, pointers: Pointers dumping. -* dumping, putting back the pdump_opaques: Reloading phase. -* dumping, putting back the pdump_root_objects and pdump_weak_object_chains: Reloading phase. -* dumping, putting back the pdump_root_struct_ptrs: Reloading phase. -* dumping, reloading phase: Reloading phase. -* dumping, remaining issues: Remaining issues. -* dumping, reorganize the hash tables: Reloading phase. -* dumping, the header: The header. -* dynamic array: Low-Level Modules. -* dynamic binding; the specbinding stack; unwind-protects: Dynamic Binding; The specbinding Stack; Unwind-Protects. -* dynamic scoping: The Lisp Language. -* dynamic types: The Lisp Language. -* editing operations, modules for standard: Modules for Standard Editing Operations. -* Emacs 19, GNU: GNU Emacs 19. -* Emacs 20, GNU: GNU Emacs 20. -* Emacs, a history of: A History of Emacs. -* Emchar: Character-Related Data Types. -* Emchars, Bufbytes and: Bufbytes and Emchars. -* encoding, internal character: Internal Character Encoding. -* encoding, internal string: Internal String Encoding. -* encodings, internal Mule: Internal Mule Encodings. -* encodings, Mule: Encodings. -* encodings, Mule character sets and: MULE Character Sets and Encodings. -* Energize: Lucid Emacs. -* Epoch <1>: XEmacs. -* Epoch: Lucid Emacs. -* error checking: Techniques for XEmacs Developers. -* EUC (Extended Unix Code), Japanese: Japanese EUC (Extended Unix Code). -* evaluation: Evaluation. -* evaluation; stack frames; bindings: Evaluation; Stack Frames; Bindings. -* event gathering mechanism, specifics of the: Specifics of the Event Gathering Mechanism. -* event loop functions, other: Other Event Loop Functions. -* event loop, events and the: Events and the Event Loop. -* event stream callback routines, the: The Event Stream Callback Routines. -* event, specifics about the Lisp object: Specifics About the Emacs Event. -* events and the event loop: Events and the Event Loop. -* events, converting: Converting Events. -* events, introduction to: Introduction to Events. -* events, main loop: Main Loop. -* events; the command builder, dispatching: Dispatching Events; The Command Builder. -* Extbyte: Character-Related Data Types. -* Extcount: Character-Related Data Types. -* Extended Unix Code, Japanese EUC: Japanese EUC (Extended Unix Code). -* extent fragments: Extent Fragments. -* extent info, format of the: Format of the Extent Info. -* extent mathematics: Mathematics of Extent Ordering. -* extent ordering <1>: Mathematics of Extent Ordering. -* extent ordering: Extent Ordering. -* extents: Extents. -* extents, display order: Mathematics of Extent Ordering. -* extents, introduction to: Introduction to Extents. -* extents, markers and: Markers and Extents. -* extents, zero-length: Zero-Length Extents. -* external data, conversion to and from: Conversion to and from External Data. -* external widget: Modules for Interfacing with X Windows. -* faces: Faces. -* file system, modules for interfacing with the: Modules for Interfacing with the File System. -* flusher: Lstream Methods. -* fragments, extent: Extent Fragments. -* frames; windows, consoles; devices;: Consoles; Devices; Frames; Windows. -* frames; windows, introduction to consoles; devices;: Introduction to Consoles; Devices; Frames; Windows. -* Free Software Foundation: A History of Emacs. -* frob blocks, allocation from: Allocation from Frob Blocks. -* FSF: A History of Emacs. -* FSF Emacs <1>: GNU Emacs 20. -* FSF Emacs: GNU Emacs 19. -* function, compiled: Compiled Function. -* garbage collection: Garbage Collection. -* garbage collection - step by step: Garbage Collection - Step by Step. -* garbage collection protection <1>: GCPROing. -* garbage collection protection: Writing Lisp Primitives. -* garbage collection, conservative: GCPROing. -* garbage collection, invocation: Invocation. -* garbage_collect_1: garbage_collect_1. -* gc_sweep: gc_sweep. -* GCPROing: GCPROing. -* global Lisp variables, adding: Adding Global Lisp Variables. -* glyph instantiation: Glyphs. -* glyphs: Glyphs. -* GNU Emacs 19: GNU Emacs 19. -* GNU Emacs 20: GNU Emacs 20. -* Gosling, James <1>: The Lisp Language. -* Gosling, James: Through Version 18. -* Great Usenet Renaming: Through Version 18. -* Hackers (Steven Levy): A History of Emacs. -* header files, inline functions: Techniques for XEmacs Developers. -* hierarchy of windows: Window Hierarchy. -* history of Emacs, a: A History of Emacs. -* Illinois, University of: XEmacs. -* INC_CHARPTR: Working With Character and Byte Positions. -* inline functions: Techniques for XEmacs Developers. -* inline functions, headers: Techniques for XEmacs Developers. -* inside, XEmacs from the: XEmacs From the Inside. -* instantiation, glyph: Glyphs. -* integers and characters: Integers and Characters. -* interactive: Modules for Standard Editing Operations. -* interfacing with the file system, modules for: Modules for Interfacing with the File System. -* interfacing with the operating system, modules for: Modules for Interfacing with the Operating System. -* interfacing with X Windows, modules for: Modules for Interfacing with X Windows. -* internal character encoding: Internal Character Encoding. -* internal Mule encodings: Internal Mule Encodings. -* internal string encoding: Internal String Encoding. -* internationalization, modules for: Modules for Internationalization. -* interning: The XEmacs Object System (Abstractly Speaking). -* interpreter and object system, modules for other aspects of the Lisp: Modules for Other Aspects of the Lisp Interpreter and Object System. -* ITS (Incompatible Timesharing System): A History of Emacs. -* Japanese EUC (Extended Unix Code): Japanese EUC (Extended Unix Code). -* Java: The Lisp Language. -* Java vs. Lisp: The Lisp Language. -* JIS7: JIS7. -* Jones, Kyle: XEmacs. -* Kaplan, Simon: XEmacs. -* Levy, Steven: A History of Emacs. -* library, Lucid Widget: Lucid Widget Library. -* line start cache: Line Start Cache. -* Lisp interpreter and object system, modules for other aspects of the: Modules for Other Aspects of the Lisp Interpreter and Object System. -* Lisp language, the: The Lisp Language. -* Lisp modules, basic: Basic Lisp Modules. -* Lisp object types, creating: Techniques for XEmacs Developers. -* Lisp objects are represented in C, how: How Lisp Objects Are Represented in C. -* Lisp objects, allocation of in XEmacs: Allocation of Objects in XEmacs Lisp. -* Lisp objects, modules for other display-related: Modules for other Display-Related Lisp Objects. -* Lisp objects, modules for the basic displayable: Modules for the Basic Displayable Lisp Objects. -* Lisp primitives, writing: Writing Lisp Primitives. -* Lisp reader and compiler, the: The Lisp Reader and Compiler. -* Lisp vs. C: The Lisp Language. -* Lisp vs. Java: The Lisp Language. -* low-level allocation: Low-level allocation. -* low-level modules: Low-Level Modules. -* lrecords: lrecords. -* lstream: Modules for Interfacing with the File System. -* lstream functions: Lstream Functions. -* lstream methods: Lstream Methods. -* lstream types: Lstream Types. -* lstream, creating an: Creating an Lstream. -* Lstream_close: Lstream Functions. -* Lstream_fgetc: Lstream Functions. -* Lstream_flush: Lstream Functions. -* Lstream_fputc: Lstream Functions. -* Lstream_fungetc: Lstream Functions. -* Lstream_getc: Lstream Functions. -* Lstream_new: Lstream Functions. -* Lstream_putc: Lstream Functions. -* Lstream_read: Lstream Functions. -* Lstream_reopen: Lstream Functions. -* Lstream_rewind: Lstream Functions. -* Lstream_set_buffering: Lstream Functions. -* Lstream_ungetc: Lstream Functions. -* Lstream_unread: Lstream Functions. -* Lstream_write: Lstream Functions. -* lstreams: Lstreams. -* Lucid Emacs: Lucid Emacs. -* Lucid Inc.: Lucid Emacs. -* Lucid Widget Library: Lucid Widget Library. -* macro hygiene: Techniques for XEmacs Developers. -* main loop: Main Loop. -* mark and sweep: Garbage Collection. -* mark method <1>: lrecords. -* mark method: Modules for Other Aspects of the Lisp Interpreter and Object System. -* mark_object: mark_object. -* marker <1>: Lstream Methods. -* marker: Marker. -* markers and extents: Markers and Extents. -* mathematics of extent ordering: Mathematics of Extent Ordering. -* MAX_EMCHAR_LEN: Working With Character and Byte Positions. -* menubars: Menubars. -* menus: Menus. -* merging attempts: XEmacs. -* MIT: A History of Emacs. -* Mlynarik, Richard: GNU Emacs 19. -* modules for interfacing with the file system: Modules for Interfacing with the File System. -* modules for interfacing with the operating system: Modules for Interfacing with the Operating System. -* modules for interfacing with X Windows: Modules for Interfacing with X Windows. -* modules for internationalization: Modules for Internationalization. -* modules for other aspects of the Lisp interpreter and object system: Modules for Other Aspects of the Lisp Interpreter and Object System. -* modules for other display-related Lisp objects: Modules for other Display-Related Lisp Objects. -* modules for regression testing: Modules for Regression Testing. -* modules for standard editing operations: Modules for Standard Editing Operations. -* modules for the basic displayable Lisp objects: Modules for the Basic Displayable Lisp Objects. -* modules for the redisplay mechanism: Modules for the Redisplay Mechanism. -* modules, a summary of the various XEmacs: A Summary of the Various XEmacs Modules. -* modules, basic Lisp: Basic Lisp Modules. -* modules, editor-level control flow: Editor-Level Control Flow Modules. -* modules, low-level: Low-Level Modules. -* MS-Windows environment, widget-glyphs in the: Glyphs. -* Mule character sets and encodings: MULE Character Sets and Encodings. -* Mule encodings: Encodings. -* Mule encodings, internal: Internal Mule Encodings. -* MULE merged XEmacs appears: XEmacs. -* Mule, coding for: Coding for Mule. -* Mule-aware code, an example of: An Example of Mule-Aware Code. -* Mule-aware code, general guidelines for writing: General Guidelines for Writing Mule-Aware Code. -* NAS: Modules for Interfacing with the Operating System. -* native sound: Modules for Interfacing with the Operating System. -* network connections: Modules for Interfacing with the Operating System. -* network sound: Modules for Interfacing with the Operating System. -* Niksic, Hrvoje: XEmacs. -* obarrays: Obarrays. -* object system (abstractly speaking), the XEmacs: The XEmacs Object System (Abstractly Speaking). -* object system, modules for other aspects of the Lisp interpreter and: Modules for Other Aspects of the Lisp Interpreter and Object System. -* object types, creating Lisp: Techniques for XEmacs Developers. -* object, the buffer: The Buffer Object. -* object, the window: The Window Object. -* objects are represented in C, how Lisp: How Lisp Objects Are Represented in C. -* objects in XEmacs Lisp, allocation of: Allocation of Objects in XEmacs Lisp. -* objects, modules for the basic displayable Lisp: Modules for the Basic Displayable Lisp Objects. -* operating system, modules for interfacing with the: Modules for Interfacing with the Operating System. -* outside, XEmacs from the: XEmacs From the Outside. -* pane: Modules for the Basic Displayable Lisp Objects. -* permanent objects: The XEmacs Object System (Abstractly Speaking). -* pi, calculating: XEmacs From the Outside. -* point: Point. -* pointers dumping: Pointers dumping. -* positions, working with character and byte: Working With Character and Byte Positions. -* primitives, writing Lisp: Writing Lisp Primitives. -* progress bars: Progress Bars. -* protection, garbage collection: GCPROing. -* pseudo_closer: Lstream Methods. -* Purify: Techniques for XEmacs Developers. -* Quantify: Techniques for XEmacs Developers. -* radio buttons, checkboxes and: Checkboxes and Radio Buttons. -* read syntax: The XEmacs Object System (Abstractly Speaking). -* read-eval-print: XEmacs From the Outside. -* reader: Lstream Methods. -* reader and compiler, the Lisp: The Lisp Reader and Compiler. -* redisplay mechanism, modules for the: Modules for the Redisplay Mechanism. -* redisplay mechanism, the: The Redisplay Mechanism. -* redisplay piece by piece: Redisplay Piece by Piece. -* redisplay sections, critical: Critical Redisplay Sections. -* regression testing, modules for: Modules for Regression Testing. -* reloading phase: Reloading phase. -* relocating allocator: Low-Level Modules. -* rename to XEmacs: XEmacs. -* represented in C, how Lisp objects are: How Lisp Objects Are Represented in C. -* rewinder: Lstream Methods. -* RMS: A History of Emacs. -* scanner: Modules for Other Aspects of the Lisp Interpreter and Object System. -* scoping, dynamic: The Lisp Language. -* scrollbars: Scrollbars. -* seekable_p: Lstream Methods. -* selections: Modules for Interfacing with X Windows. -* set_charptr_emchar: Working With Character and Byte Positions. -* Sexton, Harlan: Lucid Emacs. -* sound, native: Modules for Interfacing with the Operating System. -* sound, network: Modules for Interfacing with the Operating System. -* SPARCWorks: XEmacs. -* specbinding stack; unwind-protects, dynamic binding; the: Dynamic Binding; The specbinding Stack; Unwind-Protects. -* special forms, simple: Simple Special Forms. -* specifiers: Specifiers. -* stack frames; bindings, evaluation;: Evaluation; Stack Frames; Bindings. -* Stallman, Richard: A History of Emacs. -* string: String. -* string encoding, internal: Internal String Encoding. -* subprocesses: Subprocesses. -* subprocesses, asynchronous: Modules for Interfacing with the Operating System. -* subprocesses, synchronous: Modules for Interfacing with the Operating System. -* Sun Microsystems: XEmacs. -* sweep_bit_vectors_1: sweep_bit_vectors_1. -* sweep_lcrecords_1: sweep_lcrecords_1. -* sweep_strings: sweep_strings. -* symbol: Symbol. -* symbol values: Symbol Values. -* symbols and variables: Symbols and Variables. -* symbols, introduction to: Introduction to Symbols. -* synchronous subprocesses: Modules for Interfacing with the Operating System. -* tab controls: Tab Controls. -* taxes, doing: XEmacs From the Outside. -* techniques for XEmacs developers: Techniques for XEmacs Developers. -* TECO: A History of Emacs. -* temporary objects: The XEmacs Object System (Abstractly Speaking). -* testing, regression: Regression Testing XEmacs. -* text in a buffer, the: The Text in a Buffer. -* textual representation, buffers and: Buffers and Textual Representation. -* Thompson, Chuck: XEmacs. -* throw, catch and: Catch and Throw. -* types, dynamic: The Lisp Language. -* types, lstream: Lstream Types. -* types, proper use of unsigned: Proper Use of Unsigned Types. -* University of Illinois: XEmacs. -* unsigned types, proper use of: Proper Use of Unsigned Types. -* unwind-protects, dynamic binding; the specbinding stack;: Dynamic Binding; The specbinding Stack; Unwind-Protects. -* values, symbol: Symbol Values. -* variables, adding global Lisp: Adding Global Lisp Variables. -* variables, symbols and: Symbols and Variables. -* vector: Vector. -* vector, bit: Bit Vector. -* version 18, through: Through Version 18. -* version 19, GNU Emacs: GNU Emacs 19. -* version 20, GNU Emacs: GNU Emacs 20. -* widget interface, generic: Generic Widget Interface. -* widget library, Lucid: Lucid Widget Library. -* widget-glyphs: Glyphs. -* widget-glyphs in the MS-Windows environment: Glyphs. -* widget-glyphs in the X environment: Glyphs. -* Win-Emacs: XEmacs. -* window (in Emacs): Modules for the Basic Displayable Lisp Objects. -* window hierarchy: Window Hierarchy. -* window object, the: The Window Object. -* window point internals: The Window Object. -* windows, consoles; devices; frames;: Consoles; Devices; Frames; Windows. -* windows, introduction to consoles; devices; frames;: Introduction to Consoles; Devices; Frames; Windows. -* Wing, Ben: XEmacs. -* writer: Lstream Methods. -* writing good comments: Writing Good Comments. -* writing Lisp primitives: Writing Lisp Primitives. -* writing Mule-aware code, general guidelines for: General Guidelines for Writing Mule-Aware Code. -* writing new C code, rules when: Rules When Writing New C Code. -* X environment, widget-glyphs in the: Glyphs. -* X Window System, interface to the: Interface to the X Window System. -* X Windows, modules for interfacing with: Modules for Interfacing with X Windows. -* XEmacs: XEmacs. -* XEmacs from the inside: XEmacs From the Inside. -* XEmacs from the outside: XEmacs From the Outside. -* XEmacs from the perspective of building: XEmacs From the Perspective of Building. -* XEmacs goes it alone: XEmacs. -* XEmacs object system (abstractly speaking), the: The XEmacs Object System (Abstractly Speaking). -* Zawinski, Jamie: Lucid Emacs. -* zero-length extents: Zero-Length Extents. - - diff -u -r -N xemacs-21.4.14/info/lispref.info xemacs-21.4.15/info/lispref.info --- xemacs-21.4.14/info/lispref.info 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/lispref.info 2004-02-02 22:01:06.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/lispref.info, produced by makeinfo version 4.5 from +This is ../info/lispref.info, produced by makeinfo version 4.6 from lispref/lispref.texi. INFO-DIR-SECTION XEmacs Editor @@ -52,889 +52,849 @@  Indirect: lispref.info-1: 2366 -lispref.info-2: 50056 -lispref.info-3: 99921 -lispref.info-4: 147717 -lispref.info-5: 197557 -lispref.info-6: 247296 -lispref.info-7: 295650 -lispref.info-8: 344057 -lispref.info-9: 392723 -lispref.info-10: 437804 -lispref.info-11: 486736 -lispref.info-12: 535603 -lispref.info-13: 584135 -lispref.info-14: 633396 -lispref.info-15: 681405 -lispref.info-16: 724061 -lispref.info-17: 772972 -lispref.info-18: 822200 -lispref.info-19: 871890 -lispref.info-20: 919687 -lispref.info-21: 965322 -lispref.info-22: 1014508 -lispref.info-23: 1056572 -lispref.info-24: 1106205 -lispref.info-25: 1153220 -lispref.info-26: 1202059 -lispref.info-27: 1251702 -lispref.info-28: 1296661 -lispref.info-29: 1346093 -lispref.info-30: 1395224 -lispref.info-31: 1443361 -lispref.info-32: 1493204 -lispref.info-33: 1539502 -lispref.info-34: 1585786 -lispref.info-35: 1635776 -lispref.info-36: 1677625 -lispref.info-37: 1724126 -lispref.info-38: 1773527 -lispref.info-39: 1810570 -lispref.info-40: 1858625 -lispref.info-41: 1905677 -lispref.info-42: 1952173 -lispref.info-43: 1996031 -lispref.info-44: 2044724 -lispref.info-45: 2089108 -lispref.info-46: 2133492 -lispref.info-47: 2180133 -lispref.info-48: 2220976 -lispref.info-49: 2270049 -lispref.info-50: 2283919 +lispref.info-2: 299153 +lispref.info-3: 596434 +lispref.info-4: 894447 +lispref.info-5: 1194382 +lispref.info-6: 1492927 +lispref.info-7: 1792530 +lispref.info-8: 2092512 +lispref.info-9: 2304231  Tag Table: (Indirect) Node: Top2366 -Node: Copying50056 -Node: Introduction69212 -Node: Caveats70797 -Node: Lisp History72476 -Node: Conventions73732 -Node: Some Terms74547 -Node: nil and t75268 -Node: Evaluation Notation76945 -Node: Printing Notation77858 -Node: Error Messages78732 -Node: Buffer Text Notation79173 -Node: Format of Descriptions80048 -Node: A Sample Function Description80902 -Node: A Sample Variable Description84888 -Node: Acknowledgements85796 -Node: Packaging87774 -Node: Package Overview89365 -Node: The User's View91554 -Node: The Library Maintainer's View98026 -Node: Infrastructure99921 -Node: Control Files103615 -Node: Obtaining105822 -Node: The Package Release Engineer's View106350 -Node: Package Terminology107092 -Node: Building Packages109898 -Node: Local.rules File112632 -Node: Creating Packages116879 -Node: package-compile.el121617 -Node: package-info.in Fields123878 -Node: Makefile Variables129336 -Node: Makefile Targets134733 -Node: Issues136844 -Node: Lisp Data Types136959 -Node: Printed Representation139511 -Node: Comments141553 -Node: Primitive Types142450 -Node: Programming Types144109 -Node: Integer Type146061 -Node: Floating Point Type147098 -Node: Character Type147717 -Node: Symbol Type155621 -Node: Sequence Type158316 -Node: Cons Cell Type159835 -Node: Dotted Pair Notation164319 -Node: Association List Type166440 -Node: Array Type167323 -Node: String Type168789 -Node: Vector Type171470 -Node: Bit Vector Type172242 -Node: Function Type173104 -Node: Macro Type174217 -Node: Primitive Function Type174914 -Node: Compiled-Function Type176440 -Node: Autoload Type176994 -Node: Char Table Type178008 -Node: Hash Table Type178182 -Node: Range Table Type179337 -Node: Weak List Type180190 -Node: Editing Types180340 -Node: Buffer Type181967 -Node: Marker Type183994 -Node: Extent Type184718 -Node: Window Type185986 -Node: Frame Type187397 -Node: Device Type188192 -Node: Console Type189018 -Node: Window Configuration Type190219 -Node: Event Type190917 -Node: Process Type191081 -Node: Stream Type192116 -Node: Keymap Type193239 -Node: Syntax Table Type193777 -Node: Display Table Type194800 -Node: Database Type195239 -Node: Charset Type195405 -Node: Coding System Type195569 -Node: ToolTalk Message Type195753 -Node: ToolTalk Pattern Type195952 -Node: Window-System Types196124 -Node: Face Type197270 -Node: Glyph Type197401 -Node: Specifier Type197557 -Node: Font Instance Type197730 -Node: Color Instance Type197920 -Node: Image Instance Type198117 -Node: Toolbar Button Type198315 -Node: Subwindow Type198508 -Node: X Resource Type198687 -Node: Type Predicates198840 -Node: Equality Predicates207969 -Node: Numbers212780 -Node: Integer Basics214235 -Node: Float Basics216584 -Node: Predicates on Numbers218326 -Node: Comparison of Numbers219959 -Node: Numeric Conversions223780 -Node: Arithmetic Operations225246 -Node: Rounding Operations231385 -Node: Bitwise Operations232498 -Node: Math Functions241544 -Node: Random Numbers244077 -Node: Strings and Characters245843 -Node: String Basics247296 -Node: Predicates for Strings249714 -Node: Creating Strings250477 -Node: Predicates for Characters255818 -Node: Character Codes256889 -Node: Text Comparison258309 -Node: String Conversion261754 -Node: Modifying Strings265424 -Node: String Properties266065 -Node: Formatting Strings266710 -Node: Character Case276328 -Node: Case Tables279882 -Node: Char Tables283853 -Node: Char Table Types285245 -Node: Working With Char Tables286830 -Node: Lists288847 -Node: Cons Cells289970 -Node: Lists as Boxes291306 -Node: List-related Predicates293948 -Node: List Elements295650 -Node: Building Lists300679 -Node: Modifying Lists306671 -Node: Setcar307483 -Node: Setcdr309914 -Node: Rearrangement312435 -Node: Sets And Lists318021 -Node: Association Lists322249 -Ref: Association Lists-Footnote-1331540 -Node: Property Lists331745 -Node: Working With Normal Plists333293 -Node: Working With Lax Plists335630 -Node: Converting Plists To/From Alists337910 -Node: Weak Lists339258 -Node: Sequences Arrays Vectors341421 -Node: Sequence Functions344057 -Node: Arrays347716 -Node: Array Functions350780 -Node: Vectors353313 -Node: Vector Functions354811 -Node: Bit Vectors357382 -Node: Bit Vector Functions358227 -Node: Symbols360526 -Node: Symbol Components361575 -Node: Definitions365758 -Node: Creating Symbols367983 -Node: Symbol Properties375017 -Node: Plists and Alists376544 -Node: Object Plists378293 -Node: Other Plists381053 -Node: Evaluation382852 -Node: Intro Eval383657 -Ref: Intro Eval-Footnote-1387010 -Node: Eval387145 -Node: Forms391564 -Node: Self-Evaluating Forms392723 -Node: Symbol Forms394236 -Node: Classifying Lists395153 -Node: Function Indirection395909 -Node: Function Forms399008 -Node: Macro Forms400005 -Node: Special Forms401605 -Node: Autoloading403914 -Node: Quoting404412 -Node: Control Structures405773 -Node: Sequencing407393 -Node: Conditionals410258 -Node: Combining Conditions413681 -Node: Iteration416951 -Node: Nonlocal Exits418730 -Node: Catch and Throw419432 -Node: Examples of Catch423271 -Node: Errors425290 -Node: Signaling Errors426779 -Node: Processing of Errors435526 -Node: Handling Errors437804 -Node: Error Symbols445045 -Node: Cleanups449001 -Node: Variables452779 -Node: Global Variables454548 -Node: Constant Variables455624 -Node: Local Variables456250 -Node: Void Variables461188 -Node: Defining Variables464704 -Node: Accessing Variables471868 -Node: Setting Variables473293 -Node: Variable Scoping477812 -Node: Scope479411 -Node: Extent480936 -Node: Impl of Scope482415 -Node: Using Scoping484378 -Node: Buffer-Local Variables485900 -Node: Intro to Buffer-Local486736 -Node: Creating Buffer-Local489279 -Node: Default Value495178 -Node: Variable Aliases498321 -Node: Functions500172 -Node: What Is a Function501266 -Node: Lambda Expressions505312 -Node: Lambda Components506222 -Node: Simple Lambda508054 -Node: Argument List509711 -Node: Function Documentation513439 -Node: Function Names515381 -Node: Defining Functions517954 -Node: Calling Functions520994 -Node: Mapping Functions524842 -Node: Anonymous Functions527540 -Node: Function Cells530785 -Node: Inline Functions535603 -Node: Related Topics537413 -Node: Macros538466 -Node: Simple Macro539750 -Node: Expansion540485 -Node: Compiling Macros543489 -Node: Defining Macros545325 -Node: Backquote546642 -Node: Problems with Macros549039 -Node: Argument Evaluation549734 -Node: Surprising Local Vars552649 -Node: Eval During Expansion554717 -Node: Repeated Expansion556410 -Node: Customization558326 -Node: Common Keywords558795 -Node: Group Definitions561640 -Node: Variable Definitions563832 -Node: Customization Types568822 -Node: Simple Types570257 -Node: Composite Types572414 -Node: Splicing into Lists577104 -Node: Type Keywords578939 -Node: Loading582460 -Node: How Programs Do Loading584135 -Node: Autoload593261 -Node: Repeated Loading599331 -Node: Named Features601444 -Node: Unloading607874 -Node: Hooks for Loading610030 -Node: Byte Compilation610747 -Node: Speed of Byte-Code612814 -Node: Compilation Functions614021 -Node: Compilation Options620794 -Node: Docs and Compilation630728 -Node: Dynamic Loading633396 -Node: Eval During Compile635775 -Node: Compiled-Function Objects637040 -Node: Disassembly641841 -Node: Different Behavior649122 -Node: Debugging650467 -Node: Debugger651879 -Node: Error Debugging653024 -Node: Infinite Loops655777 -Node: Function Debugging657021 -Node: Explicit Debug659821 -Node: Using Debugger660592 -Node: Debugger Commands662454 -Node: Invoking the Debugger666771 -Node: Internals of Debugger670686 -Node: Syntax Errors675573 -Node: Excess Open676821 -Node: Excess Close678696 -Node: Compilation Errors680117 -Node: Edebug681405 -Node: Using Edebug683513 -Node: Instrumenting686210 -Node: Edebug Execution Modes689699 -Node: Jumping692809 -Node: Edebug Misc695153 -Node: Breakpoints696542 -Node: Global Break Condition699348 -Node: Embedded Breakpoints700303 -Node: Trapping Errors701258 -Node: Edebug Views703334 -Node: Edebug Eval705300 -Node: Eval List706477 -Node: Reading in Edebug709862 -Node: Printing in Edebug710661 -Node: Tracing712376 -Node: Coverage Testing714264 -Node: The Outside Context716305 -Node: Checking Whether to Stop717254 -Node: Edebug Display Update717901 -Node: Edebug Recursive Edit719924 -Node: Instrumenting Macro Calls721579 -Node: Specification List724061 -Node: Backtracking733474 -Node: Debugging Backquote735412 -Node: Specification Examples739118 -Node: Edebug Options741185 -Node: Read and Print746524 -Node: Streams Intro747501 -Node: Input Streams749519 -Node: Input Functions754420 -Node: Output Streams756480 -Node: Output Functions760531 -Node: Output Variables764831 -Node: Minibuffers769632 -Node: Intro to Minibuffers770784 -Node: Text from Minibuffer772972 -Node: Object from Minibuffer778066 -Node: Minibuffer History782159 -Node: Completion785138 -Node: Basic Completion787113 -Node: Minibuffer Completion791996 -Node: Completion Commands795573 -Node: High-Level Completion800230 -Node: Reading File Names804979 -Node: Programmed Completion808671 -Node: Yes-or-No Queries811053 -Node: Multiple Queries816790 -Node: Reading a Password820857 -Node: Minibuffer Misc822200 -Node: Command Loop827080 -Node: Command Overview828424 -Node: Defining Commands831702 -Node: Using Interactive832450 -Node: Interactive Codes837223 -Node: Interactive Examples843015 -Node: Interactive Call844329 -Node: Command Loop Info849744 -Node: Events854723 -Node: Event Types856184 -Node: Event Contents858107 -Node: Event Predicates862583 -Node: Accessing Mouse Event Positions863901 -Node: Frame-Level Event Position Info864600 -Node: Window-Level Event Position Info865640 -Node: Event Text Position Info867404 -Node: Event Glyph Position Info869896 -Node: Event Toolbar Position Info871219 -Node: Other Event Position Info871890 -Node: Accessing Other Event Info872299 -Node: Working With Events873919 -Node: Converting Events879920 -Node: Reading Input883319 -Node: Key Sequence Input884321 -Node: Reading One Event886956 -Node: Dispatching an Event889780 -Node: Quoted Character Input890231 -Node: Peeking and Discarding891579 -Node: Waiting895484 -Node: Quitting897798 -Node: Prefix Command Arguments902206 -Node: Recursive Editing907293 -Node: Disabling Commands912088 -Node: Command History914156 -Node: Keyboard Macros915893 -Node: Keymaps918110 -Node: Keymap Terminology919687 -Node: Format of Keymaps922616 -Node: Creating Keymaps923027 -Node: Inheritance and Keymaps925107 -Node: Key Sequences927479 -Node: Prefix Keys932275 -Node: Active Keymaps935860 -Node: Key Lookup945231 -Node: Functions for Key Lookup950394 -Node: Changing Key Bindings956095 -Node: Key Binding Commands963257 -Node: Scanning Keymaps965322 -Node: Other Keymap Functions973891 -Node: Menus974513 -Node: Menu Format975105 -Node: Menubar Format983751 -Node: Menubar984376 -Node: Modifying Menus987489 -Node: Menu Filters992833 -Node: Pop-Up Menus994729 -Node: Menu Accelerators997057 -Node: Creating Menu Accelerators997813 -Node: Keyboard Menu Traversal999173 -Node: Menu Accelerator Functions999900 -Node: Buffers Menu1002976 -Node: Dialog Boxes1004270 -Node: Dialog Box Format1004437 -Node: Dialog Box Functions1005862 -Node: Toolbar1006259 -Node: Toolbar Intro1006694 -Node: Creating Toolbar1009094 -Node: Toolbar Descriptor Format1010011 -Node: Specifying the Toolbar1014508 -Node: Other Toolbar Variables1018115 -Node: Gutter1022543 -Node: Gutter Intro1023132 -Node: Creating Gutter1025135 -Node: Gutter Descriptor Format1028022 -Node: Specifying a Gutter1032479 -Node: Other Gutter Variables1036014 -Node: Common Gutter Widgets1040401 -Node: Buffer Tabs1041393 -Node: Progress Bars1041534 -Node: Scrollbars1041679 -Node: Drag and Drop1041814 -Node: Supported Protocols1042890 -Node: OffiX DND1043393 -Node: CDE dt1044400 -Node: MSWindows OLE1044991 -Node: Loose ends1045162 -Node: Drop Interface1045554 -Node: Drag Interface1046577 -Node: Modes1046751 -Node: Major Modes1047702 -Node: Major Mode Conventions1050617 -Node: Example Major Modes1056572 -Node: Auto Major Mode1064605 -Node: Mode Help1072055 -Node: Derived Modes1073156 -Node: Minor Modes1075347 -Node: Minor Mode Conventions1076649 -Node: Keymaps and Minor Modes1079512 -Node: Modeline Format1080347 -Node: Modeline Data1082115 -Node: Modeline Variables1087268 -Node: %-Constructs1091984 -Node: Hooks1094971 -Node: Documentation1101731 -Node: Documentation Basics1103154 -Node: Accessing Documentation1106205 -Node: Keys in Documentation1112486 -Node: Describing Characters1115969 -Node: Help Functions1118318 -Node: Obsoleteness1124768 -Node: Files1127760 -Node: Visiting Files1129685 -Node: Visiting Functions1131190 -Node: Subroutines of Visiting1136348 -Node: Saving Buffers1138421 -Node: Reading from Files1144514 -Node: Writing to Files1146675 -Node: File Locks1149392 -Node: Information about Files1152459 -Node: Testing Accessibility1153220 -Node: Kinds of Files1156960 -Node: Truenames1158641 -Node: File Attributes1159643 -Node: Changing File Attributes1164782 -Node: File Names1170204 -Node: File Name Components1171777 -Node: Directory Names1174222 -Node: Relative File Names1177452 -Node: File Name Expansion1178422 -Node: Unique File Names1182176 -Node: File Name Completion1183791 -Node: User Name Completion1187059 -Node: Contents of Directories1188466 -Node: Create/Delete Dirs1191779 -Node: Magic File Names1192885 -Node: Partial Files1198533 -Node: Intro to Partial Files1198761 -Node: Creating a Partial File1200001 -Node: Detached Partial Files1200937 -Node: Format Conversion1202059 -Node: Files and MS-DOS1207557 -Node: Backups and Auto-Saving1209621 -Node: Backup Files1210296 -Node: Making Backups1211693 -Node: Rename or Copy1214442 -Node: Numbered Backups1216935 -Node: Backup Names1219170 -Node: Auto-Saving1222462 -Node: Reverting1230624 -Node: Buffers1233960 -Node: Buffer Basics1235376 -Node: Current Buffer1237429 -Node: Buffer Names1242133 -Node: Buffer File Name1245340 -Node: Buffer Modification1249459 -Node: Modification Time1251702 -Node: Read Only Buffers1255077 -Node: The Buffer List1258316 -Node: Creating Buffers1263133 -Node: Killing Buffers1265279 -Node: Indirect Buffers1269111 -Node: Windows1271685 -Node: Basic Windows1273163 -Node: Splitting Windows1276261 -Node: Deleting Windows1281587 -Node: Selecting Windows1285505 -Node: Cyclic Window Ordering1289728 -Node: Buffers and Windows1294883 -Node: Displaying Buffers1296661 -Node: Choosing Window1302000 -Node: Window Point1309918 -Node: Window Start1311988 -Node: Vertical Scrolling1316787 -Node: Horizontal Scrolling1322985 -Node: Size of Window1326514 -Node: Position of Window1331232 -Node: Resizing Windows1333485 -Node: Window Configurations1338923 -Node: Frames1342412 -Node: Creating Frames1344753 -Node: Frame Properties1346093 -Node: Property Access1346909 -Node: Initial Properties1347816 -Node: X Frame Properties1350302 -Node: Size and Position1354936 -Node: Frame Name1356934 -Node: Frame Titles1357848 -Node: Deleting Frames1359672 -Node: Finding All Frames1360647 -Node: Frames and Windows1363875 -Node: Minibuffers and Frames1366657 -Node: Input Focus1367575 -Node: Visibility of Frames1370680 -Node: Raising and Lowering1372670 -Node: Frame Configurations1375046 -Node: Frame Hooks1376103 -Node: Consoles and Devices1377908 -Node: Basic Console Functions1380651 -Node: Basic Device Functions1381074 -Node: Console Types and Device Classes1381920 -Node: Connecting to a Console or Device1384187 -Node: The Selected Console and Device1386371 -Node: Console and Device I/O1387397 -Node: Positions1388161 -Node: Point1389130 -Node: Motion1392220 -Node: Character Motion1392987 -Node: Word Motion1395224 -Node: Buffer End Motion1396614 -Node: Text Lines1398151 -Node: Screen Lines1403052 -Node: List Motion1407115 -Node: Skipping Characters1410598 -Node: Excursions1412817 -Node: Narrowing1415857 -Node: Markers1421188 -Node: Overview of Markers1422094 -Node: Predicates on Markers1426786 -Node: Creating Markers1428032 -Node: Information from Markers1432232 -Node: Changing Markers1433330 -Node: The Mark1434858 -Node: The Region1443361 -Node: Text1449047 -Node: Near Point1451746 -Node: Buffer Contents1455933 -Node: Comparing Text1457339 -Node: Insertion1458747 -Node: Commands for Insertion1462657 -Node: Deletion1465551 -Node: User-Level Deletion1469201 -Node: The Kill Ring1473361 -Node: Kill Ring Concepts1475535 -Node: Kill Functions1476589 -Node: Yank Commands1478512 -Node: Low-Level Kill Ring1480383 -Node: Internals of Kill Ring1483469 -Node: Undo1486249 -Node: Maintaining Undo1490586 -Node: Filling1493204 -Node: Margins1499198 -Node: Auto Filling1503221 -Node: Sorting1504402 -Node: Columns1513716 -Node: Indentation1516797 -Node: Primitive Indent1517576 -Node: Mode-Specific Indent1518901 -Node: Region Indent1521433 -Node: Relative Indent1524380 -Node: Indent Tabs1526762 -Node: Motion by Indent1528083 -Node: Case Changes1528862 -Node: Text Properties1532215 -Node: Examining Properties1534028 -Node: Changing Properties1535911 -Node: Property Search1539502 -Node: Special Properties1544221 -Node: Saving Properties1544502 -Node: Substitution1547644 -Node: Registers1550914 -Node: Transposition1553497 -Node: Change Hooks1554391 -Node: Transformations1556431 -Node: Searching and Matching1561534 -Node: String Search1562665 -Node: Regular Expressions1567646 -Node: Syntax of Regexps1569013 -Node: Regexp Example1583616 -Node: Regexp Search1585786 -Node: POSIX Regexps1592123 -Node: Search and Replace1594200 -Node: Match Data1597565 -Node: Simple Match Data1598695 -Node: Replacing Match1602960 -Node: Entire Match Data1605641 -Node: Saving Match Data1607879 -Node: Searching and Case1609267 -Node: Standard Regexps1611301 -Node: Syntax Tables1613499 -Node: Syntax Basics1614613 -Node: Syntax Descriptors1617595 -Node: Syntax Class Table1619445 -Node: Syntax Flags1625627 -Node: Syntax Table Functions1630026 -Node: Motion and Syntax1634324 -Node: Parsing Expressions1635776 -Node: Standard Syntax Tables1641874 -Node: Syntax Table Internals1642718 -Node: Abbrevs1643744 -Node: Abbrev Mode1645548 -Node: Abbrev Tables1646268 -Node: Defining Abbrevs1647807 -Node: Abbrev Files1649728 -Node: Abbrev Expansion1651511 -Node: Standard Abbrev Tables1656142 -Node: Extents1657301 -Node: Intro to Extents1658544 -Node: Creating and Modifying Extents1662536 -Node: Extent Endpoints1664117 -Node: Finding Extents1667380 -Node: Mapping Over Extents1671502 -Node: Extent Properties1677625 -Node: Detached Extents1687851 -Node: Extent Parents1689710 -Node: Duplicable Extents1691404 -Node: Extents and Events1694625 -Node: Atomic Extents1696587 -Node: Specifiers1697034 -Node: Introduction to Specifiers1699147 -Node: Specifiers In-Depth1701457 -Node: Specifier Instancing1706369 -Node: Specifier Types1709631 -Node: Adding Specifications1714705 -Node: Retrieving Specifications1724126 -Node: Specifier Tag Functions1727871 -Node: Specifier Instancing Functions1731105 -Node: Specifier Example1734512 -Node: Creating Specifiers1737668 -Node: Specifier Validation Functions1741985 -Node: Other Specification Functions1744371 -Node: Faces and Window-System Objects1748192 -Node: Faces1748516 -Node: Merging Faces1750133 -Node: Basic Face Functions1752094 -Node: Face Properties1754242 -Node: Face Convenience Functions1764515 -Node: Other Face Display Functions1767735 -Node: Fonts1768547 -Node: Font Specifiers1769248 -Node: Font Instances1770433 -Node: Font Instance Names1771400 -Node: Font Instance Size1772241 -Node: Font Instance Characteristics1773527 -Node: Font Convenience Functions1774705 -Node: Colors1775995 -Node: Color Specifiers1776435 -Node: Color Instances1778795 -Node: Color Instance Properties1779539 -Node: Color Convenience Functions1780165 -Node: Glyphs1781218 -Node: Glyph Functions1782880 -Node: Creating Glyphs1783287 -Node: Glyph Properties1795927 -Node: Glyph Convenience Functions1805094 -Node: Glyph Dimensions1809041 -Node: Images1810121 -Node: Image Specifiers1810570 -Node: Image Instantiator Conversion1826061 -Node: Image Instances1827426 -Node: Image Instance Types1828177 -Node: Image Instance Functions1830942 -Node: Glyph Types1837999 -Node: Mouse Pointer1839771 -Node: Redisplay Glyphs1842774 -Node: Subwindows1843807 -Node: Glyph Examples1844073 -Node: Annotations1852332 -Node: Annotation Basics1853348 -Node: Annotation Primitives1857286 -Node: Annotation Properties1858625 -Node: Locating Annotations1861665 -Node: Margin Primitives1862502 -Node: Annotation Hooks1864396 -Node: Display1865056 -Node: Refresh Screen1866034 -Node: Truncation1868228 -Node: The Echo Area1870753 -Node: Warnings1877196 -Node: Invisible Text1881632 -Node: Selective Display1884346 -Node: Overlay Arrow1888472 -Node: Temporary Displays1889825 -Node: Blinking1893946 -Node: Usual Display1896130 -Node: Display Tables1898679 -Node: Display Table Format1899483 -Node: Active Display Table1900925 -Node: Character Descriptors1904920 -Node: Beeping1905677 -Node: Hash Tables1910443 -Node: Introduction to Hash Tables1911051 -Node: Working With Hash Tables1917610 -Node: Weak Hash Tables1918727 -Node: Range Tables1920744 -Node: Introduction to Range Tables1921433 -Node: Working With Range Tables1921879 -Node: Databases1922838 -Node: Connecting to a Database1923137 -Node: Working With a Database1924244 -Node: Other Database Functions1925118 -Node: Processes1925687 -Node: Subprocess Creation1927911 -Node: Synchronous Processes1931362 -Node: MS-DOS Subprocesses1938084 -Node: Asynchronous Processes1939158 -Node: Deleting Processes1943515 -Node: Process Information1945386 -Node: Input to Processes1949478 -Node: Signals to Processes1952173 -Node: Output from Processes1956988 -Node: Process Buffers1957800 -Node: Filter Functions1960679 -Node: Accepting Output1966270 -Node: Sentinels1967797 -Node: Process Window Size1971287 -Node: Transaction Queues1971636 -Node: Network1973334 -Node: System Interface1975968 -Node: Starting Up1977238 -Node: Start-up Summary1977832 -Node: Init File1981386 -Node: Terminal-Specific1983767 -Node: Command Line Arguments1986926 -Node: Getting Out1990415 -Node: Killing XEmacs1990984 -Node: Suspending XEmacs1992652 -Node: System Environment1996031 -Node: User Identification2002212 -Node: Time of Day2005741 -Node: Time Conversion2008528 -Node: Timers2013770 -Node: Terminal Input2015943 -Node: Input Modes2016446 -Node: Translating Input2018905 -Node: Recording Input2023070 -Node: Terminal Output2025170 -Node: Flow Control2028791 -Node: Batch Mode2032753 -Node: X-Windows2034135 -Node: X Selections2035006 -Node: X Server2037757 -Node: Resources2038208 -Node: Server Data2043517 -Node: Grabs2044724 -Node: X Miscellaneous2046304 -Node: ToolTalk Support2048689 -Node: XEmacs ToolTalk API Summary2048906 -Node: Sending Messages2050206 -Node: Example of Sending Messages2050457 -Node: Elisp Interface for Sending Messages2051519 -Node: Receiving Messages2058115 -Node: Example of Receiving Messages2058338 -Node: Elisp Interface for Receiving Messages2059174 -Node: LDAP Support2063031 -Node: Building XEmacs with LDAP support2063525 -Node: XEmacs LDAP API2064502 -Node: LDAP Variables2065554 -Node: The High-Level LDAP API2068154 -Node: The Low-Level LDAP API2071627 -Node: The LDAP Lisp Object2072458 -Node: Opening and Closing a LDAP Connection2073013 -Node: Low-level Operations on a LDAP Server2074828 -Node: LDAP Internationalization2077552 -Node: LDAP Internationalization Variables2078457 -Node: Encoder/Decoder Functions2080188 -Node: Syntax of Search Filters2081225 -Node: PostgreSQL Support2082523 -Node: Building XEmacs with PostgreSQL support2082918 -Node: XEmacs PostgreSQL libpq API2084265 -Node: libpq Lisp Variables2086144 -Node: libpq Lisp Symbols and DataTypes2089108 -Node: Synchronous Interface Functions2102364 -Node: Asynchronous Interface Functions2106854 -Node: Large Object Support2110359 -Node: Other libpq Functions2110986 -Node: Unimplemented libpq Functions2114021 -Node: XEmacs PostgreSQL libpq Examples2119340 -Node: Internationalization2125431 -Node: I18N Levels 1 and 22125774 -Node: I18N Level 32126480 -Node: Level 3 Basics2126761 -Node: Level 3 Primitives2127594 -Node: Dynamic Messaging2129200 -Node: Domain Specification2129663 -Node: Documentation String Extraction2131333 -Node: I18N Level 42132251 -Node: MULE2132443 -Node: Internationalization Terminology2133492 -Node: Charsets2145691 -Node: Charset Properties2146387 -Node: Basic Charset Functions2151102 -Node: Charset Property Functions2153283 -Node: Predefined Charsets2155501 -Node: MULE Characters2158421 -Node: Composite Characters2159296 -Node: Coding Systems2160563 -Node: Coding System Types2162703 -Node: ISO 20222166687 -Node: EOL Conversion2178961 -Node: Coding System Properties2180133 -Node: Basic Coding System Functions2184456 -Node: Coding System Property Functions2186490 -Node: Encoding and Decoding Text2187048 -Node: Detection of Textual Encoding2188184 -Node: Big5 and Shift-JIS Functions2189720 -Node: Predefined Coding Systems2190872 -Node: CCL2202967 -Node: CCL Syntax2206071 -Node: CCL Statements2207647 -Node: CCL Expressions2212295 -Node: Calling CCL2214834 -Node: CCL Examples2217839 -Node: Category Tables2217976 -Node: Tips2220335 -Node: Style Tips2220976 -Node: Compilation Tips2230495 -Node: Documentation Tips2232409 -Node: Comment Tips2237918 -Node: Library Headers2240921 -Node: Building XEmacs and Object Allocation2244893 -Node: Building XEmacs2245776 -Node: Pure Storage2252354 -Node: Garbage Collection2254997 -Node: Standard Errors2265840 -Node: Standard Buffer-Local Variables2270049 -Node: Standard Keymaps2272684 -Node: Standard Hooks2276418 -Node: Index2283919 +Node: Copying50069 +Node: Introduction69219 +Node: Caveats70801 +Node: Lisp History72477 +Node: Conventions73730 +Node: Some Terms74542 +Node: nil and t75260 +Node: Evaluation Notation76934 +Node: Printing Notation77845 +Node: Error Messages78715 +Node: Buffer Text Notation79153 +Node: Format of Descriptions80025 +Node: A Sample Function Description80876 +Node: A Sample Variable Description84859 +Node: Acknowledgements85764 +Node: Packaging87739 +Node: Package Overview89486 +Node: The User View91666 +Node: The Library Maintainer View98125 +Node: Infrastructure100037 +Node: Control Files103981 +Node: Obtaining106049 +Node: The Package Release Engineer View106563 +Node: Package Terminology107294 +Node: Building Packages110118 +Node: Makefile Targets111327 +Node: Local.rules File113188 +Node: Creating Packages120123 +Node: package-info.in120657 +Node: Makefile125512 +Node: Documenting Packages139309 +Node: Issues140602 +Node: Lisp Data Types140717 +Node: Printed Representation143266 +Node: Comments145305 +Node: Primitive Types146199 +Node: Programming Types147855 +Node: Integer Type149804 +Node: Floating Point Type150838 +Node: Character Type151454 +Node: Symbol Type159355 +Node: Sequence Type162047 +Node: Cons Cell Type163563 +Node: Dotted Pair Notation168044 +Node: Association List Type170162 +Node: Array Type171042 +Node: String Type172505 +Node: Vector Type175183 +Node: Bit Vector Type175952 +Node: Function Type176811 +Node: Macro Type177921 +Node: Primitive Function Type178615 +Node: Compiled-Function Type180138 +Node: Autoload Type180689 +Node: Char Table Type181700 +Node: Hash Table Type181871 +Node: Range Table Type183022 +Node: Weak List Type183872 +Node: Editing Types184019 +Node: Buffer Type185643 +Node: Marker Type187667 +Node: Extent Type188387 +Node: Window Type189652 +Node: Frame Type191060 +Node: Device Type191852 +Node: Console Type192675 +Node: Window Configuration Type193873 +Node: Event Type194568 +Node: Process Type194729 +Node: Stream Type195761 +Node: Keymap Type196881 +Node: Syntax Table Type197416 +Node: Display Table Type198435 +Node: Database Type198872 +Node: Charset Type199035 +Node: Coding System Type199196 +Node: ToolTalk Message Type199377 +Node: ToolTalk Pattern Type199573 +Node: Window-System Types199742 +Node: Face Type200885 +Node: Glyph Type201013 +Node: Specifier Type201166 +Node: Font Instance Type201336 +Node: Color Instance Type201523 +Node: Image Instance Type201717 +Node: Toolbar Button Type201912 +Node: Subwindow Type202102 +Node: X Resource Type202278 +Node: Type Predicates202428 +Node: Equality Predicates211554 +Node: Numbers216362 +Node: Integer Basics217814 +Node: Float Basics220160 +Node: Predicates on Numbers221899 +Node: Comparison of Numbers223529 +Node: Numeric Conversions227347 +Node: Arithmetic Operations228810 +Node: Rounding Operations234946 +Node: Bitwise Operations236056 +Node: Math Functions245099 +Node: Random Numbers247631 +Node: Strings and Characters249394 +Node: String Basics250844 +Node: Predicates for Strings253259 +Node: Creating Strings254019 +Node: Predicates for Characters259357 +Node: Character Codes260428 +Node: Text Comparison261848 +Node: String Conversion265293 +Node: Modifying Strings268960 +Node: String Properties269598 +Node: Formatting Strings270240 +Node: Character Case279855 +Node: Case Tables283406 +Node: Char Tables287373 +Node: Char Table Types288763 +Node: Working With Char Tables290345 +Node: Lists292362 +Node: Cons Cells293482 +Node: Lists as Boxes294815 +Node: List-related Predicates297454 +Node: List Elements299153 +Node: Building Lists304179 +Node: Modifying Lists310167 +Node: Setcar310976 +Node: Setcdr313404 +Node: Rearrangement315922 +Node: Sets And Lists321505 +Node: Association Lists325730 +Ref: Association Lists-Footnote-1335018 +Node: Property Lists335223 +Node: Working With Normal Plists336768 +Node: Working With Lax Plists339105 +Node: Converting Plists To/From Alists341382 +Node: Weak Lists342730 +Node: Sequences Arrays Vectors344890 +Node: Sequence Functions347523 +Node: Arrays351179 +Node: Array Functions354240 +Node: Vectors356770 +Node: Vector Functions358265 +Node: Bit Vectors360833 +Node: Bit Vector Functions361675 +Node: Symbols363971 +Node: Symbol Components365017 +Node: Definitions369197 +Node: Creating Symbols371419 +Node: Symbol Properties378450 +Node: Plists and Alists379974 +Node: Object Plists381720 +Node: Other Plists384477 +Node: Evaluation386273 +Node: Intro Eval387075 +Ref: Intro Eval-Footnote-1390425 +Node: Eval390560 +Node: Forms394976 +Node: Self-Evaluating Forms396133 +Node: Symbol Forms397643 +Node: Classifying Lists398557 +Node: Function Indirection399310 +Node: Function Forms402406 +Node: Macro Forms403400 +Node: Special Forms404997 +Node: Autoloading407303 +Node: Quoting407798 +Node: Control Structures409156 +Node: Sequencing410774 +Node: Conditionals413636 +Node: Combining Conditions417056 +Node: Iteration420323 +Node: Nonlocal Exits422099 +Node: Catch and Throw422797 +Node: Examples of Catch426633 +Node: Errors428649 +Node: Signaling Errors430135 +Node: Processing of Errors438879 +Node: Handling Errors441154 +Node: Error Symbols448390 +Node: Cleanups452343 +Node: Variables456118 +Node: Global Variables457885 +Node: Constant Variables458958 +Node: Local Variables459581 +Node: Void Variables464516 +Node: Defining Variables468029 +Node: Accessing Variables475190 +Node: Setting Variables476612 +Node: Variable Scoping481128 +Node: Scope482724 +Node: Extent484247 +Node: Impl of Scope485723 +Node: Using Scoping487683 +Node: Buffer-Local Variables489202 +Node: Intro to Buffer-Local490035 +Node: Creating Buffer-Local492575 +Node: Default Value498474 +Node: Variable Aliases501614 +Node: Functions503462 +Node: What Is a Function504553 +Node: Lambda Expressions508596 +Node: Lambda Components509503 +Node: Simple Lambda511328 +Node: Argument List512982 +Node: Function Documentation516707 +Node: Function Names518646 +Node: Defining Functions521216 +Node: Calling Functions524253 +Node: Mapping Functions528098 +Node: Anonymous Functions530795 +Node: Function Cells534037 +Node: Inline Functions538852 +Node: Related Topics540659 +Node: Macros541709 +Node: Simple Macro542990 +Node: Expansion543722 +Node: Compiling Macros546723 +Node: Defining Macros548556 +Node: Backquote549870 +Node: Problems with Macros552264 +Node: Argument Evaluation552955 +Node: Surprising Local Vars555867 +Node: Eval During Expansion557929 +Node: Repeated Expansion559619 +Node: Customization561532 +Node: Common Keywords561998 +Node: Group Definitions564839 +Node: Variable Definitions567029 +Node: Customization Types572016 +Node: Simple Types573448 +Node: Composite Types575602 +Node: Splicing into Lists580289 +Node: Type Keywords582121 +Node: Loading585639 +Node: How Programs Do Loading587311 +Node: Autoload596434 +Node: Repeated Loading602501 +Node: Named Features604611 +Node: Unloading611038 +Node: Hooks for Loading613191 +Node: Byte Compilation613908 +Node: Speed of Byte-Code615972 +Node: Compilation Functions617176 +Node: Compilation Options623946 +Node: Docs and Compilation633876 +Node: Dynamic Loading636541 +Node: Eval During Compile638917 +Node: Compiled-Function Objects640179 +Node: Disassembly644977 +Node: Different Behavior652255 +Node: Debugging653597 +Node: Debugger655006 +Node: Error Debugging656148 +Node: Infinite Loops658898 +Node: Function Debugging660139 +Node: Explicit Debug662936 +Node: Using Debugger663704 +Node: Debugger Commands665563 +Node: Invoking the Debugger669877 +Node: Internals of Debugger673789 +Node: Syntax Errors678673 +Node: Excess Open679918 +Node: Excess Close681790 +Node: Compilation Errors683208 +Node: Edebug684493 +Node: Using Edebug686598 +Node: Instrumenting689292 +Node: Edebug Execution Modes692778 +Node: Jumping695885 +Node: Edebug Misc698226 +Node: Breakpoints699612 +Node: Global Break Condition702415 +Node: Embedded Breakpoints703367 +Node: Trapping Errors704319 +Node: Edebug Views706392 +Node: Edebug Eval708355 +Node: Eval List709529 +Node: Reading in Edebug712911 +Node: Printing in Edebug713707 +Node: Tracing715419 +Node: Coverage Testing717304 +Node: The Outside Context719342 +Node: Checking Whether to Stop720288 +Node: Edebug Display Update720932 +Node: Edebug Recursive Edit722952 +Node: Instrumenting Macro Calls724604 +Node: Specification List727082 +Node: Backtracking736492 +Node: Debugging Backquote738427 +Node: Specification Examples742130 +Node: Edebug Options744194 +Node: Read and Print749530 +Node: Streams Intro750504 +Node: Input Streams752519 +Node: Input Functions757417 +Node: Output Streams759474 +Node: Output Functions763522 +Node: Output Variables767819 +Node: Minibuffers772620 +Node: Intro to Minibuffers773769 +Node: Text from Minibuffer775954 +Node: Object from Minibuffer781045 +Node: Minibuffer History785135 +Node: Completion788111 +Node: Basic Completion790083 +Node: Minibuffer Completion794963 +Node: Completion Commands798537 +Node: High-Level Completion803191 +Node: Reading File Names807937 +Node: Programmed Completion811626 +Node: Yes-or-No Queries814005 +Node: Multiple Queries819739 +Node: Reading a Password823803 +Node: Minibuffer Misc825143 +Node: Command Loop830020 +Node: Command Overview831361 +Node: Defining Commands834635 +Node: Using Interactive835380 +Node: Interactive Codes840150 +Node: Interactive Examples845939 +Node: Interactive Call847250 +Node: Command Loop Info852661 +Node: Events857637 +Node: Event Types859095 +Node: Event Contents861015 +Node: Event Predicates865489 +Node: Accessing Mouse Event Positions866804 +Node: Frame-Level Event Position Info867500 +Node: Window-Level Event Position Info868537 +Node: Event Text Position Info870298 +Node: Event Glyph Position Info872787 +Node: Event Toolbar Position Info874107 +Node: Other Event Position Info874778 +Node: Accessing Other Event Info875187 +Node: Working With Events876804 +Node: Converting Events882802 +Node: Reading Input886198 +Node: Key Sequence Input887197 +Node: Reading One Event889829 +Node: Dispatching an Event892650 +Node: Quoted Character Input893101 +Node: Peeking and Discarding894447 +Node: Waiting898349 +Node: Quitting900660 +Node: Prefix Command Arguments905065 +Node: Recursive Editing910149 +Node: Disabling Commands914940 +Node: Command History917005 +Node: Keyboard Macros918739 +Node: Keymaps920953 +Node: Keymap Terminology922527 +Node: Format of Keymaps925453 +Node: Creating Keymaps925861 +Node: Inheritance and Keymaps927938 +Node: Key Sequences930307 +Node: Prefix Keys935100 +Node: Active Keymaps938682 +Node: Key Lookup948050 +Node: Functions for Key Lookup953210 +Node: Changing Key Bindings958908 +Node: Key Binding Commands966067 +Node: Scanning Keymaps968129 +Node: Other Keymap Functions976695 +Node: Menus977317 +Node: Menu Format977909 +Node: Menubar Format986552 +Node: Menubar987174 +Node: Modifying Menus990287 +Node: Menu Filters995628 +Node: Pop-Up Menus997521 +Node: Menu Accelerators999849 +Node: Creating Menu Accelerators1000602 +Node: Keyboard Menu Traversal1001959 +Node: Menu Accelerator Functions1002684 +Node: Buffers Menu1005779 +Node: Dialog Boxes1007070 +Node: Dialog Box Format1007237 +Node: Dialog Box Functions1008659 +Node: Toolbar1009056 +Node: Toolbar Intro1009491 +Node: Creating Toolbar1011889 +Node: Toolbar Descriptor Format1012806 +Node: Specifying the Toolbar1017300 +Node: Other Toolbar Variables1020904 +Node: Gutter1025329 +Node: Gutter Intro1025915 +Node: Creating Gutter1027915 +Node: Gutter Descriptor Format1030802 +Node: Specifying a Gutter1035256 +Node: Other Gutter Variables1038788 +Node: Common Gutter Widgets1043172 +Node: Buffer Tabs1044161 +Node: Progress Bars1044299 +Node: Scrollbars1044441 +Node: Drag and Drop1044573 +Node: Supported Protocols1045646 +Node: OffiX DND1046146 +Node: CDE dt1047150 +Node: MSWindows OLE1047738 +Node: Loose ends1047906 +Node: Drop Interface1048295 +Node: Drag Interface1049315 +Node: Modes1049486 +Node: Major Modes1050434 +Node: Major Mode Conventions1053346 +Node: Example Major Modes1059298 +Node: Auto Major Mode1067329 +Node: Mode Help1074776 +Node: Derived Modes1075874 +Node: Minor Modes1078062 +Node: Minor Mode Conventions1079361 +Node: Keymaps and Minor Modes1082221 +Node: Modeline Format1083053 +Node: Modeline Data1084818 +Node: Modeline Variables1089968 +Node: %-Constructs1094681 +Node: Hooks1097665 +Node: Documentation1104422 +Node: Documentation Basics1105842 +Node: Accessing Documentation1108890 +Node: Keys in Documentation1115171 +Node: Describing Characters1118651 +Node: Help Functions1120997 +Node: Obsoleteness1127444 +Node: Files1130433 +Node: Visiting Files1132355 +Node: Visiting Functions1133857 +Node: Subroutines of Visiting1139013 +Node: Saving Buffers1141083 +Node: Reading from Files1147173 +Node: Writing to Files1149331 +Node: File Locks1152045 +Node: Information about Files1155109 +Node: Testing Accessibility1155867 +Node: Kinds of Files1159604 +Node: Truenames1161282 +Node: File Attributes1162281 +Node: Changing File Attributes1167417 +Node: File Names1172836 +Node: File Name Components1174405 +Node: Directory Names1176847 +Node: Relative File Names1180074 +Node: File Name Expansion1181040 +Node: Unique File Names1184791 +Node: File Name Completion1186403 +Node: User Name Completion1189668 +Node: Contents of Directories1191072 +Node: Create/Delete Dirs1194382 +Node: Magic File Names1195485 +Node: Partial Files1201130 +Node: Intro to Partial Files1201358 +Node: Creating a Partial File1202595 +Node: Detached Partial Files1203531 +Node: Format Conversion1204650 +Node: Files and MS-DOS1210145 +Node: Backups and Auto-Saving1212206 +Node: Backup Files1212878 +Node: Making Backups1214272 +Node: Rename or Copy1217021 +Node: Numbered Backups1219511 +Node: Backup Names1221743 +Node: Auto-Saving1225032 +Node: Reverting1233191 +Node: Buffers1236524 +Node: Buffer Basics1237937 +Node: Current Buffer1239983 +Node: Buffer Names1244684 +Node: Buffer File Name1247888 +Node: Buffer Modification1252004 +Node: Modification Time1254244 +Node: Read Only Buffers1257616 +Node: The Buffer List1260852 +Node: Creating Buffers1265666 +Node: Killing Buffers1267809 +Node: Indirect Buffers1271638 +Node: Windows1274209 +Node: Basic Windows1275684 +Node: Splitting Windows1278779 +Node: Deleting Windows1284102 +Node: Selecting Windows1288017 +Node: Cyclic Window Ordering1292237 +Node: Buffers and Windows1297389 +Node: Displaying Buffers1299164 +Node: Choosing Window1304500 +Node: Window Point1312415 +Node: Window Start1314482 +Node: Vertical Scrolling1319278 +Node: Horizontal Scrolling1325473 +Node: Size of Window1328999 +Node: Position of Window1333714 +Node: Resizing Windows1335964 +Node: Window Configurations1341399 +Node: Frames1344885 +Node: Creating Frames1347223 +Node: Frame Properties1348560 +Node: Property Access1349373 +Node: Initial Properties1350277 +Node: X Frame Properties1352760 +Node: Size and Position1357391 +Node: Frame Name1359386 +Node: Frame Titles1360297 +Node: Deleting Frames1362118 +Node: Finding All Frames1363089 +Node: Frames and Windows1366317 +Node: Minibuffers and Frames1369096 +Node: Input Focus1370011 +Node: Visibility of Frames1373113 +Node: Raising and Lowering1375100 +Node: Frame Configurations1377473 +Node: Frame Hooks1378527 +Node: Consoles and Devices1380329 +Node: Basic Console Functions1383069 +Node: Basic Device Functions1383492 +Node: Console Types and Device Classes1384338 +Node: Connecting to a Console or Device1386602 +Node: The Selected Console and Device1388786 +Node: Console and Device I/O1389812 +Node: Positions1390576 +Node: Point1391543 +Node: Motion1394630 +Node: Character Motion1395394 +Node: Word Motion1397629 +Node: Buffer End Motion1399016 +Node: Text Lines1400550 +Node: Screen Lines1405447 +Node: List Motion1409507 +Node: Skipping Characters1412987 +Node: Excursions1415203 +Node: Narrowing1418240 +Node: Markers1423568 +Node: Overview of Markers1424471 +Node: Predicates on Markers1429160 +Node: Creating Markers1430403 +Node: Information from Markers1434600 +Node: Changing Markers1435695 +Node: The Mark1437220 +Node: The Region1445721 +Node: Text1451433 +Node: Near Point1454129 +Node: Buffer Contents1458313 +Node: Comparing Text1459716 +Node: Insertion1461121 +Node: Commands for Insertion1465028 +Node: Deletion1467919 +Node: User-Level Deletion1471566 +Node: The Kill Ring1475723 +Node: Kill Ring Concepts1477894 +Node: Kill Functions1478945 +Node: Yank Commands1480865 +Node: Low-Level Kill Ring1482733 +Node: Internals of Kill Ring1485816 +Node: Undo1488593 +Node: Maintaining Undo1492927 +Node: Filling1495542 +Node: Margins1501533 +Node: Auto Filling1505556 +Node: Sorting1506734 +Node: Columns1516045 +Node: Indentation1519123 +Node: Primitive Indent1519899 +Node: Mode-Specific Indent1521221 +Node: Region Indent1523750 +Node: Relative Indent1526694 +Node: Indent Tabs1529073 +Node: Motion by Indent1530391 +Node: Case Changes1531167 +Node: Text Properties1534517 +Node: Examining Properties1536327 +Node: Changing Properties1538207 +Node: Property Search1541795 +Node: Special Properties1546511 +Node: Saving Properties1546789 +Node: Substitution1549928 +Node: Registers1553195 +Node: Transposition1555774 +Node: Change Hooks1556665 +Node: Transformations1558702 +Node: Searching and Matching1563802 +Node: String Search1564930 +Node: Regular Expressions1569908 +Node: Syntax of Regexps1571272 +Node: Regexp Example1585872 +Node: Regexp Search1588039 +Node: POSIX Regexps1594373 +Node: Search and Replace1596447 +Node: Match Data1599812 +Node: Simple Match Data1600939 +Node: Replacing Match1605201 +Node: Entire Match Data1607879 +Node: Saving Match Data1610114 +Node: Searching and Case1611499 +Node: Standard Regexps1613530 +Node: Syntax Tables1615725 +Node: Syntax Basics1616836 +Node: Syntax Descriptors1619812 +Node: Syntax Class Table1621659 +Node: Syntax Flags1627838 +Node: Syntax Table Functions1632234 +Node: Motion and Syntax1636529 +Node: Parsing Expressions1637978 +Node: Standard Syntax Tables1644073 +Node: Syntax Table Internals1644914 +Node: Abbrevs1645937 +Node: Abbrev Mode1647738 +Node: Abbrev Tables1648455 +Node: Defining Abbrevs1649991 +Node: Abbrev Files1651909 +Node: Abbrev Expansion1653689 +Node: Standard Abbrev Tables1658317 +Node: Extents1659473 +Node: Intro to Extents1660712 +Node: Creating and Modifying Extents1664701 +Node: Extent Endpoints1666282 +Node: Finding Extents1669542 +Node: Mapping Over Extents1673661 +Node: Extent Properties1679781 +Node: Detached Extents1690001 +Node: Extent Parents1691857 +Node: Duplicable Extents1693548 +Node: Extents and Events1696766 +Node: Atomic Extents1698724 +Node: Specifiers1699168 +Node: Introduction to Specifiers1701297 +Node: Simple Specifier Usage1705478 +Node: Specifiers In-Depth1711896 +Node: Specifier Instancing1718530 +Node: Specifier Types1721789 +Node: Adding Specifications1726860 +Node: Retrieving Specifications1738350 +Node: Specifier Tag Functions1742095 +Node: Specifier Instancing Functions1745326 +Node: Specifier Examples1750181 +Node: Creating Specifiers1757885 +Node: Specifier Validation Functions1762228 +Node: Other Specification Functions1764614 +Node: Faces and Window-System Objects1768496 +Node: Faces1768820 +Node: Merging Faces1770434 +Node: Basic Face Functions1772392 +Node: Face Properties1774537 +Node: Face Convenience Functions1784807 +Node: Other Face Display Functions1788027 +Node: Fonts1788839 +Node: Font Specifiers1789537 +Node: Font Instances1790722 +Node: Font Instance Names1791689 +Node: Font Instance Size1792530 +Node: Font Instance Characteristics1793816 +Node: Font Convenience Functions1794994 +Node: Colors1796284 +Node: Color Specifiers1796724 +Node: Color Instances1799084 +Node: Color Instance Properties1799825 +Node: Color Convenience Functions1800451 +Node: Glyphs1801504 +Node: Glyph Functions1803163 +Node: Creating Glyphs1803570 +Node: Glyph Properties1816210 +Node: Glyph Convenience Functions1825374 +Node: Glyph Dimensions1829318 +Node: Images1830398 +Node: Image Specifiers1830847 +Node: Image Instantiator Conversion1846336 +Node: Image Instances1847701 +Node: Image Instance Types1848449 +Node: Image Instance Functions1851211 +Node: Glyph Types1858268 +Node: Mouse Pointer1860037 +Node: Redisplay Glyphs1863037 +Node: Subwindows1864070 +Node: Glyph Examples1864333 +Node: Annotations1872589 +Node: Annotation Basics1873602 +Node: Annotation Primitives1877537 +Node: Annotation Properties1878876 +Node: Locating Annotations1881916 +Node: Margin Primitives1882753 +Node: Annotation Hooks1884644 +Node: Display1885301 +Node: Refresh Screen1886276 +Node: Truncation1888467 +Node: The Echo Area1890989 +Node: Warnings1897429 +Node: Invisible Text1901862 +Node: Selective Display1904573 +Node: Overlay Arrow1908696 +Node: Temporary Displays1910046 +Node: Blinking1914165 +Node: Usual Display1916346 +Node: Display Tables1918892 +Node: Display Table Format1919693 +Node: Active Display Table1921132 +Node: Character Descriptors1925124 +Node: Beeping1925878 +Node: Hash Tables1930643 +Node: Introduction to Hash Tables1931251 +Node: Working With Hash Tables1937807 +Node: Weak Hash Tables1938924 +Node: Range Tables1940938 +Node: Introduction to Range Tables1941624 +Node: Working With Range Tables1942070 +Node: Databases1943029 +Node: Connecting to a Database1943328 +Node: Working With a Database1944435 +Node: Other Database Functions1945309 +Node: Processes1945878 +Node: Subprocess Creation1948099 +Node: Synchronous Processes1951547 +Node: MS-DOS Subprocesses1958266 +Node: Asynchronous Processes1959337 +Node: Deleting Processes1963691 +Node: Process Information1965559 +Node: Input to Processes1969649 +Node: Signals to Processes1972341 +Node: Output from Processes1977153 +Node: Process Buffers1977962 +Node: Filter Functions1980838 +Node: Accepting Output1986426 +Node: Sentinels1987950 +Node: Process Window Size1991437 +Node: Transaction Queues1991786 +Node: Network1993481 +Node: System Interface1996112 +Node: Starting Up1997379 +Node: Start-up Summary1997970 +Node: Init File2001521 +Node: Terminal-Specific2003899 +Node: Command Line Arguments2007055 +Node: Getting Out2010541 +Node: Killing XEmacs2011107 +Node: Suspending XEmacs2012772 +Node: System Environment2016148 +Node: User Identification2022326 +Node: Time of Day2025855 +Node: Time Conversion2028639 +Node: Timers2033878 +Node: Terminal Input2036048 +Node: Input Modes2036548 +Node: Translating Input2039007 +Node: Recording Input2043169 +Node: Terminal Output2045269 +Node: Flow Control2048887 +Node: Batch Mode2052846 +Node: X-Windows2054224 +Node: X Selections2055093 +Node: X Server2057841 +Node: Resources2058289 +Node: Server Data2063598 +Node: Grabs2064802 +Node: X Miscellaneous2066382 +Node: ToolTalk Support2068767 +Node: XEmacs ToolTalk API Summary2068984 +Node: Sending Messages2070281 +Node: Example of Sending Messages2070532 +Node: Elisp Interface for Sending Messages2071591 +Node: Receiving Messages2078187 +Node: Example of Receiving Messages2078410 +Node: Elisp Interface for Receiving Messages2079243 +Node: LDAP Support2083100 +Node: Building XEmacs with LDAP support2083591 +Node: XEmacs LDAP API2084565 +Node: LDAP Variables2085614 +Node: The High-Level LDAP API2088214 +Node: The Low-Level LDAP API2091684 +Node: The LDAP Lisp Object2092512 +Node: Opening and Closing a LDAP Connection2093064 +Node: Low-level Operations on a LDAP Server2094879 +Node: LDAP Internationalization2097600 +Node: LDAP Internationalization Variables2098502 +Node: Encoder/Decoder Functions2100233 +Node: Syntax of Search Filters2101278 +Node: PostgreSQL Support2102572 +Node: Building XEmacs with PostgreSQL support2102964 +Node: XEmacs PostgreSQL libpq API2104308 +Node: libpq Lisp Variables2106184 +Node: libpq Lisp Symbols and DataTypes2109178 +Node: Synchronous Interface Functions2122435 +Node: Asynchronous Interface Functions2126939 +Node: Large Object Support2130441 +Node: Other libpq Functions2131068 +Node: Unimplemented libpq Functions2134105 +Node: XEmacs PostgreSQL libpq Examples2139424 +Node: Internationalization2145512 +Node: I18N Levels 1 and 22145855 +Node: I18N Level 32146558 +Node: Level 3 Basics2146839 +Node: Level 3 Primitives2147670 +Node: Dynamic Messaging2149276 +Node: Domain Specification2149736 +Node: Documentation String Extraction2151403 +Node: I18N Level 42152318 +Node: MULE2152507 +Node: Internationalization Terminology2153553 +Node: Charsets2165749 +Node: Charset Properties2166442 +Node: Basic Charset Functions2171154 +Node: Charset Property Functions2173335 +Node: Predefined Charsets2175550 +Node: MULE Characters2178467 +Node: Composite Characters2179342 +Node: Coding Systems2180606 +Node: Coding System Types2182743 +Node: ISO 20222186724 +Node: EOL Conversion2198995 +Node: Coding System Properties2200167 +Node: Basic Coding System Functions2204490 +Node: Coding System Property Functions2206524 +Node: Encoding and Decoding Text2207082 +Node: Detection of Textual Encoding2208218 +Node: Big5 and Shift-JIS Functions2209754 +Node: Predefined Coding Systems2210903 +Node: CCL2222995 +Node: CCL Syntax2226096 +Node: CCL Statements2227669 +Node: CCL Expressions2232299 +Node: Calling CCL2234835 +Node: CCL Examples2237837 +Node: Category Tables2237971 +Node: Tips2240327 +Node: Style Tips2240966 +Node: Compilation Tips2250841 +Node: Documentation Tips2252752 +Node: Comment Tips2258258 +Node: Library Headers2261259 +Node: Building XEmacs and Object Allocation2265227 +Node: Building XEmacs2266107 +Node: Pure Storage2272682 +Node: Garbage Collection2275322 +Node: Standard Errors2286163 +Node: Standard Buffer-Local Variables2290369 +Node: Standard Keymaps2293001 +Node: Standard Hooks2296733 +Node: Index2304231  End Tag Table diff -u -r -N xemacs-21.4.14/info/lispref.info-1 xemacs-21.4.15/info/lispref.info-1 --- xemacs-21.4.14/info/lispref.info-1 2003-09-03 22:39:04.000000000 -0400 +++ xemacs-21.4.15/info/lispref.info-1 2004-02-02 22:01:06.000000000 -0500 @@ -1,4 +1,4 @@ -This is ../info/lispref.info, produced by makeinfo version 4.5 from +This is ../info/lispref.info, produced by makeinfo version 4.6 from lispref/lispref.texi. INFO-DIR-SECTION XEmacs Editor @@ -193,9 +193,9 @@ Package Overview -* The User's View:: -* The Library Maintainer's View:: -* The Package Release Engineer's View:: +* The User View:: +* The Library Maintainer View:: +* The Package Release Engineer View:: The Library Maintainer's View @@ -205,9 +205,8 @@ Creating Packages -* package-compile.el:: -* package-info.in Fields:: -* Makefile Variables:: +* package-info.in:: package-info.in +* Makefile:: `Makefile' * Makefile Targets:: Lisp Data Types @@ -877,7 +876,7 @@ * Retrieving Specifications:: Querying a specifier's specifications. * Specifier Instancing Functions:: Functions to instance a specifier. -* Specifier Example:: Making all this stuff clearer. +* Specifier Examples:: Making all this stuff clearer. * Creating Specifiers:: Creating specifiers for your own use. * Specifier Validation Functions:: Validating the components of a specifier. @@ -1111,3 +1110,6308 @@ * Pure Storage:: A kludge to make preloaded Lisp functions sharable. * Garbage Collection:: Reclaiming space for Lisp objects no longer used. + +File: lispref.info, Node: Copying, Next: Introduction, Prev: Top, Up: Top + +GNU GENERAL PUBLIC LICENSE +************************** + + Version 2, June 1991 + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble +======== + +The licenses for most software are designed to take away your freedom +to share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + 0. This License applies to any program or other work which contains a + notice placed by the copyright holder saying it may be distributed + under the terms of this General Public License. The "Program", + below, refers to any such program or work, and a "work based on + the Program" means either the Program or any derivative work under + copyright law: that is to say, a work containing the Program or a + portion of it, either verbatim or with modifications and/or + translated into another language. (Hereinafter, translation is + included without limitation in the term "modification".) Each + licensee is addressed as "you". + + Activities other than copying, distribution and modification are + not covered by this License; they are outside its scope. The act + of running the Program is not restricted, and the output from the + Program is covered only if its contents constitute a work based on + the Program (independent of having been made by running the + Program). Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's + source code as you receive it, in any medium, provided that you + conspicuously and appropriately publish on each copy an appropriate + copyright notice and disclaimer of warranty; keep intact all the + notices that refer to this License and to the absence of any + warranty; and give any other recipients of the Program a copy of + this License along with the Program. + + You may charge a fee for the physical act of transferring a copy, + and you may at your option offer warranty protection in exchange + for a fee. + + 2. You may modify your copy or copies of the Program or any portion + of it, thus forming a work based on the Program, and copy and + distribute such modifications or work under the terms of Section 1 + above, provided that you also meet all of these conditions: + + a. You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b. You must cause any work that you distribute or publish, that + in whole or in part contains or is derived from the Program + or any part thereof, to be licensed as a whole at no charge + to all third parties under the terms of this License. + + c. If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display + an announcement including an appropriate copyright notice and + a notice that there is no warranty (or else, saying that you + provide a warranty) and that users may redistribute the + program under these conditions, and telling the user how to + view a copy of this License. (Exception: if the Program + itself is interactive but does not normally print such an + announcement, your work based on the Program is not required + to print an announcement.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the + Program, and can be reasonably considered independent and separate + works in themselves, then this License, and its terms, do not + apply to those sections when you distribute them as separate + works. But when you distribute the same sections as part of a + whole which is a work based on the Program, the distribution of + the whole must be on the terms of this License, whose permissions + for other licensees extend to the entire whole, and thus to each + and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or + contest your rights to work written entirely by you; rather, the + intent is to exercise the right to control the distribution of + derivative or collective works based on the Program. + + In addition, mere aggregation of another work not based on the + Program with the Program (or with a work based on the Program) on + a volume of a storage or distribution medium does not bring the + other work under the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, + under Section 2) in object code or executable form under the terms + of Sections 1 and 2 above provided that you also do one of the + following: + + a. Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Sections 1 and 2 above on a medium customarily used for + software interchange; or, + + b. Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a + medium customarily used for software interchange; or, + + c. Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with + such an offer, in accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete + source code means all the source code for all modules it contains, + plus any associated interface definition files, plus the scripts + used to control compilation and installation of the executable. + However, as a special exception, the source code distributed need + not include anything that is normally distributed (in either + source or binary form) with the major components (compiler, + kernel, and so on) of the operating system on which the executable + runs, unless that component itself accompanies the executable. + + If distribution of executable or object code is made by offering + access to copy from a designated place, then offering equivalent + access to copy the source code from the same place counts as + distribution of the source code, even though third parties are not + compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program + except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense or distribute the Program is + void, and will automatically terminate your rights under this + License. However, parties who have received copies, or rights, + from you under this License will not have their licenses + terminated so long as such parties remain in full compliance. + + 5. You are not required to accept this License, since you have not + signed it. However, nothing else grants you permission to modify + or distribute the Program or its derivative works. These actions + are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Program (or any work + based on the Program), you indicate your acceptance of this + License to do so, and all its terms and conditions for copying, + distributing or modifying the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program + subject to these terms and conditions. You may not impose any + further restrictions on the recipients' exercise of the rights + granted herein. You are not responsible for enforcing compliance + by third parties to this License. + + 7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent + issues), conditions are imposed on you (whether by court order, + agreement or otherwise) that contradict the conditions of this + License, they do not excuse you from the conditions of this + License. If you cannot distribute so as to satisfy simultaneously + your obligations under this License and any other pertinent + obligations, then as a consequence you may not distribute the + Program at all. For example, if a patent license would not permit + royalty-free redistribution of the Program by all those who + receive copies directly or indirectly through you, then the only + way you could satisfy both it and this License would be to refrain + entirely from distribution of the Program. + + If any portion of this section is held invalid or unenforceable + under any particular circumstance, the balance of the section is + intended to apply and the section as a whole is intended to apply + in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of + any such claims; this section has the sole purpose of protecting + the integrity of the free software distribution system, which is + implemented by public license practices. Many people have made + generous contributions to the wide range of software distributed + through that system in reliance on consistent application of that + system; it is up to the author/donor to decide if he or she is + willing to distribute software through any other system and a + licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed + to be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in + certain countries either by patents or by copyrighted interfaces, + the original copyright holder who places the Program under this + License may add an explicit geographical distribution limitation + excluding those countries, so that distribution is permitted only + in or among countries not thus excluded. In such case, this + License incorporates the limitation as if written in the body of + this License. + + 9. The Free Software Foundation may publish revised and/or new + versions of the General Public License from time to time. Such + new versions will be similar in spirit to the present version, but + may differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the + Program specifies a version number of this License which applies + to it and "any later version", you have the option of following + the terms and conditions either of that version or of any later + version published by the Free Software Foundation. If the Program + does not specify a version number of this License, you may choose + any version ever published by the Free Software Foundation. + + 10. If you wish to incorporate parts of the Program into other free + programs whose distribution conditions are different, write to the + author to ask for permission. For software which is copyrighted + by the Free Software Foundation, write to the Free Software + Foundation; we sometimes make exceptions for this. Our decision + will be guided by the two goals of preserving the free status of + all derivatives of our free software and of promoting the sharing + and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO + WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE + LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE + QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY + SERVICING, REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN + WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY + MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE + LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, + INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF + DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU + OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY + OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs +============================================= + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + ONE LINE TO GIVE THE PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES. + Copyright (C) 19YY NAME OF AUTHOR + + This program 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 + of the License, or (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Also add information on how to contact you by electronic and paper +mail. + + If the program is interactive, make it output a short notice like +this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details + type `show w'. This is free software, and you are welcome + to redistribute it under certain conditions; type `show c' + for details. + + The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + + You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the program, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright + interest in the program `Gnomovision' + (which makes passes at compilers) written + by James Hacker. + + SIGNATURE OF TY COON, 1 April 1989 + Ty Coon, President of Vice + + This General Public License does not permit incorporating your +program into proprietary programs. If your program is a subroutine +library, you may consider it more useful to permit linking proprietary +applications with the library. If this is what you want to do, use the +GNU Library General Public License instead of this License. + + +File: lispref.info, Node: Introduction, Next: Packaging, Prev: Copying, Up: Top + +Introduction +************ + +Most of the XEmacs text editor is written in the programming language +called XEmacs Lisp. You can write new code in XEmacs Lisp and install +it as an extension to the editor. However, XEmacs Lisp is more than a +mere "extension language"; it is a full computer programming language +in its own right. You can use it as you would any other programming +language. + + Because XEmacs Lisp is designed for use in an editor, it has special +features for scanning and parsing text as well as features for handling +files, buffers, displays, subprocesses, and so on. XEmacs Lisp is +closely integrated with the editing facilities; thus, editing commands +are functions that can also conveniently be called from Lisp programs, +and parameters for customization are ordinary Lisp variables. + + This manual describes XEmacs Lisp, presuming considerable familiarity +with the use of XEmacs for editing. (See `The XEmacs Reference +Manual', for this basic information.) Generally speaking, the earlier +chapters describe features of XEmacs Lisp that have counterparts in many +programming languages, and later chapters describe features that are +peculiar to XEmacs Lisp or relate specifically to editing. + + This is edition 3.3. + +* Menu: + +* Caveats:: Flaws and a request for help. +* Lisp History:: XEmacs Lisp is descended from Maclisp. +* Conventions:: How the manual is formatted. +* Acknowledgements:: The authors, editors, and sponsors of this manual. + + +File: lispref.info, Node: Caveats, Next: Lisp History, Up: Introduction + +Caveats +======= + +This manual has gone through numerous drafts. It is nearly complete +but not flawless. There are a few topics that are not covered, either +because we consider them secondary (such as most of the individual +modes) or because they are yet to be written. Because we are not able +to deal with them completely, we have left out several parts +intentionally. + + The manual should be fully correct in what it does cover, and it is +therefore open to criticism on anything it says--from specific examples +and descriptive text, to the ordering of chapters and sections. If +something is confusing, or you find that you have to look at the sources +or experiment to learn something not covered in the manual, then perhaps +the manual should be fixed. Please let us know. + + As you use this manual, we ask that you send corrections as soon as +you find them. If you think of a simple, real life example for a +function or group of functions, please make an effort to write it up +and send it in. Please reference any comments to the node name and +function or variable name, as appropriate. Also state the number of +the edition which you are criticizing. + + This manual was originally written for FSF Emacs 19 and was updated +by Ben Wing (ben@xemacs.org) for Lucid Emacs 19.10 and later for XEmacs +19.12, 19.13, 19.14, and 20.0. It was further updated by the XEmacs +Development Team for 19.15 and 20.1. Please send comments and +corrections relating to XEmacs-specific portions of this manual to + xemacs@xemacs.org + + or post to the newsgroup + comp.emacs.xemacs + + --Ben Wing + + +File: lispref.info, Node: Lisp History, Next: Conventions, Prev: Caveats, Up: Introduction + +Lisp History +============ + +Lisp (LISt Processing language) was first developed in the late 1950's +at the Massachusetts Institute of Technology for research in artificial +intelligence. The great power of the Lisp language makes it superior +for other purposes as well, such as writing editing commands. + + Dozens of Lisp implementations have been built over the years, each +with its own idiosyncrasies. Many of them were inspired by Maclisp, +which was written in the 1960's at MIT's Project MAC. Eventually the +implementors of the descendants of Maclisp came together and developed a +standard for Lisp systems, called Common Lisp. + + XEmacs Lisp is largely inspired by Maclisp, and a little by Common +Lisp. If you know Common Lisp, you will notice many similarities. +However, many of the features of Common Lisp have been omitted or +simplified in order to reduce the memory requirements of XEmacs. +Sometimes the simplifications are so drastic that a Common Lisp user +might be very confused. We will occasionally point out how XEmacs Lisp +differs from Common Lisp. If you don't know Common Lisp, don't worry +about it; this manual is self-contained. + + +File: lispref.info, Node: Conventions, Next: Acknowledgements, Prev: Lisp History, Up: Introduction + +Conventions +=========== + +This section explains the notational conventions that are used in this +manual. You may want to skip this section and refer back to it later. + +* Menu: + +* Some Terms:: Explanation of terms we use in this manual. +* nil and t:: How the symbols `nil' and `t' are used. +* Evaluation Notation:: The format we use for examples of evaluation. +* Printing Notation:: The format we use for examples that print output. +* Error Messages:: The format we use for examples of errors. +* Buffer Text Notation:: The format we use for buffer contents in examples. +* Format of Descriptions:: Notation for describing functions, variables, etc. + + +File: lispref.info, Node: Some Terms, Next: nil and t, Up: Conventions + +Some Terms +---------- + +Throughout this manual, the phrases "the Lisp reader" and "the Lisp +printer" are used to refer to those routines in Lisp that convert +textual representations of Lisp objects into actual Lisp objects, and +vice versa. *Note Printed Representation::, for more details. You, the +person reading this manual, are thought of as "the programmer" and are +addressed as "you". "The user" is the person who uses Lisp programs, +including those you write. + + Examples of Lisp code appear in this font or form: `(list 1 2 3)'. +Names that represent arguments or metasyntactic variables appear in +this font or form: FIRST-NUMBER. + + +File: lispref.info, Node: nil and t, Next: Evaluation Notation, Prev: Some Terms, Up: Conventions + +`nil' and `t' +------------- + +In Lisp, the symbol `nil' has three separate meanings: it is a symbol +with the name `nil'; it is the logical truth value FALSE; and it is the +empty list--the list of zero elements. When used as a variable, `nil' +always has the value `nil'. + + As far as the Lisp reader is concerned, `()' and `nil' are +identical: they stand for the same object, the symbol `nil'. The +different ways of writing the symbol are intended entirely for human +readers. After the Lisp reader has read either `()' or `nil', there is +no way to determine which representation was actually written by the +programmer. + + In this manual, we use `()' when we wish to emphasize that it means +the empty list, and we use `nil' when we wish to emphasize that it +means the truth value FALSE. That is a good convention to use in Lisp +programs also. + + (cons 'foo ()) ; Emphasize the empty list + (not nil) ; Emphasize the truth value FALSE + + In contexts where a truth value is expected, any non-`nil' value is +considered to be TRUE. However, `t' is the preferred way to represent +the truth value TRUE. When you need to choose a value which represents +TRUE, and there is no other basis for choosing, use `t'. The symbol +`t' always has value `t'. + + In XEmacs Lisp, `nil' and `t' are special symbols that always +evaluate to themselves. This is so that you do not need to quote them +to use them as constants in a program. An attempt to change their +values results in a `setting-constant' error. *Note Accessing +Variables::. + + +File: lispref.info, Node: Evaluation Notation, Next: Printing Notation, Prev: nil and t, Up: Conventions + +Evaluation Notation +------------------- + +A Lisp expression that you can evaluate is called a "form". Evaluating +a form always produces a result, which is a Lisp object. In the +examples in this manual, this is indicated with `=>': + + (car '(1 2)) + => 1 + +You can read this as "`(car '(1 2))' evaluates to 1". + + When a form is a macro call, it expands into a new form for Lisp to +evaluate. We show the result of the expansion with `==>'. We may or +may not show the actual result of the evaluation of the expanded form. + + (news-cadr '(a b c)) + ==> (car (cdr '(a b c))) + => b + + Sometimes to help describe one form we show another form that +produces identical results. The exact equivalence of two forms is +indicated with `=='. + + (cons 'a nil) == (list 'a) + + +File: lispref.info, Node: Printing Notation, Next: Error Messages, Prev: Evaluation Notation, Up: Conventions + +Printing Notation +----------------- + +Many of the examples in this manual print text when they are evaluated. +If you execute example code in a Lisp Interaction buffer (such as the +buffer `*scratch*'), the printed text is inserted into the buffer. If +you execute the example by other means (such as by evaluating the +function `eval-region'), the printed text is displayed in the echo +area. You should be aware that text displayed in the echo area is +truncated to a single line. + + Examples in this manual indicate printed text with `-|', +irrespective of where that text goes. The value returned by evaluating +the form (here `bar') follows on a separate line. + + (progn (print 'foo) (print 'bar)) + -| foo + -| bar + => bar + + +File: lispref.info, Node: Error Messages, Next: Buffer Text Notation, Prev: Printing Notation, Up: Conventions + +Error Messages +-------------- + +Some examples signal errors. This normally displays an error message +in the echo area. We show the error message on a line starting with +`error-->'. Note that `error-->' itself does not appear in the echo +area. + + (+ 23 'x) + error--> Wrong type argument: integer-or-marker-p, x + + +File: lispref.info, Node: Buffer Text Notation, Next: Format of Descriptions, Prev: Error Messages, Up: Conventions + +Buffer Text Notation +-------------------- + +Some examples show modifications to text in a buffer, with "before" and +"after" versions of the text. These examples show the contents of the +buffer in question between two lines of dashes containing the buffer +name. In addition, `-!-' indicates the location of point. (The symbol +for point, of course, is not part of the text in the buffer; it +indicates the place _between_ two characters where point is located.) + + ---------- Buffer: foo ---------- + This is the -!-contents of foo. + ---------- Buffer: foo ---------- + + (insert "changed ") + => nil + ---------- Buffer: foo ---------- + This is the changed -!-contents of foo. + ---------- Buffer: foo ---------- + + +File: lispref.info, Node: Format of Descriptions, Prev: Buffer Text Notation, Up: Conventions + +Format of Descriptions +---------------------- + +Functions, variables, macros, commands, user options, and special forms +are described in this manual in a uniform format. The first line of a +description contains the name of the item followed by its arguments, if +any. The category--function, variable, or whatever--appears at the +beginning of the line. The description follows on succeeding lines, +sometimes with examples. + +* Menu: + +* A Sample Function Description:: A description of an imaginary + function, `foo'. +* A Sample Variable Description:: A description of an imaginary + variable, + `electric-future-map'. + + +File: lispref.info, Node: A Sample Function Description, Next: A Sample Variable Description, Up: Format of Descriptions + +A Sample Function Description +............................. + +In a function description, the name of the function being described +appears first. It is followed on the same line by a list of parameters. +The names used for the parameters are also used in the body of the +description. + + The appearance of the keyword `&optional' in the parameter list +indicates that the arguments for subsequent parameters may be omitted +(omitted parameters default to `nil'). Do not write `&optional' when +you call the function. + + The keyword `&rest' (which will always be followed by a single +parameter) indicates that any number of arguments can follow. The value +of the single following parameter will be a list of all these arguments. +Do not write `&rest' when you call the function. + + Here is a description of an imaginary function `foo': + + - Function: foo integer1 &optional integer2 &rest integers + The function `foo' subtracts INTEGER1 from INTEGER2, then adds all + the rest of the arguments to the result. If INTEGER2 is not + supplied, then the number 19 is used by default. + + (foo 1 5 3 9) + => 16 + (foo 5) + => 14 + + More generally, + + (foo W X Y...) + == + (+ (- X W) Y...) + + Any parameter whose name contains the name of a type (e.g., INTEGER, +INTEGER1 or BUFFER) is expected to be of that type. A plural of a type +(such as BUFFERS) often means a list of objects of that type. +Parameters named OBJECT may be of any type. (*Note Lisp Data Types::, +for a list of XEmacs object types.) Parameters with other sorts of +names (e.g., NEW-FILE) are discussed specifically in the description of +the function. In some sections, features common to parameters of +several functions are described at the beginning. + + *Note Lambda Expressions::, for a more complete description of +optional and rest arguments. + + Command, macro, and special form descriptions have the same format, +but the word `Function' is replaced by `Command', `Macro', or `Special +Form', respectively. Commands are simply functions that may be called +interactively; macros process their arguments differently from functions +(the arguments are not evaluated), but are presented the same way. + + Special form descriptions use a more complex notation to specify +optional and repeated parameters because they can break the argument +list down into separate arguments in more complicated ways. +``[OPTIONAL-ARG]'' means that OPTIONAL-ARG is optional and +`REPEATED-ARGS...' stands for zero or more arguments. Parentheses are +used when several arguments are grouped into additional levels of list +structure. Here is an example: + + - Special Form: count-loop (VAR [FROM TO [INC]]) BODY... + This imaginary special form implements a loop that executes the + BODY forms and then increments the variable VAR on each iteration. + On the first iteration, the variable has the value FROM; on + subsequent iterations, it is incremented by 1 (or by INC if that + is given). The loop exits before executing BODY if VAR equals TO. + Here is an example: + + (count-loop (i 0 10) + (prin1 i) (princ " ") + (prin1 (aref vector i)) (terpri)) + + If FROM and TO are omitted, then VAR is bound to `nil' before the + loop begins, and the loop exits if VAR is non-`nil' at the + beginning of an iteration. Here is an example: + + (count-loop (done) + (if (pending) + (fixit) + (setq done t))) + + In this special form, the arguments FROM and TO are optional, but + must both be present or both absent. If they are present, INC may + optionally be specified as well. These arguments are grouped with + the argument VAR into a list, to distinguish them from BODY, which + includes all remaining elements of the form. + + +File: lispref.info, Node: A Sample Variable Description, Prev: A Sample Function Description, Up: Format of Descriptions + +A Sample Variable Description +............................. + +A "variable" is a name that can hold a value. Although any variable +can be set by the user, certain variables that exist specifically so +that users can change them are called "user options". Ordinary +variables and user options are described using a format like that for +functions except that there are no arguments. + + Here is a description of the imaginary `electric-future-map' +variable. + + - Variable: electric-future-map + The value of this variable is a full keymap used by Electric + Command Future mode. The functions in this map allow you to edit + commands you have not yet thought about executing. + + User option descriptions have the same format, but `Variable' is +replaced by `User Option'. + + +File: lispref.info, Node: Acknowledgements, Prev: Conventions, Up: Introduction + +Acknowledgements +================ + +This manual was based on the GNU Emacs Lisp Reference Manual, version +2.4, written by Robert Krawitz, Bil Lewis, Dan LaLiberte, Richard M. +Stallman and Chris Welty, the volunteers of the GNU manual group, in an +effort extending over several years. Robert J. Chassell helped to +review and edit the manual, with the support of the Defense Advanced +Research Projects Agency, ARPA Order 6082, arranged by Warren A. Hunt, +Jr. of Computational Logic, Inc. + + Ben Wing adapted this manual for XEmacs 19.14 and 20.0, and earlier +for Lucid Emacs 19.10, XEmacs 19.12, and XEmacs 19.13. He is the sole +author of many of the manual sections, in particular the XEmacs-specific +sections: events, faces, extents, glyphs, specifiers, toolbar, menubars, +scrollbars, dialog boxes, devices, consoles, hash tables, range tables, +char tables, databases, and others. The section on annotations was +originally written by Chuck Thompson. Corrections to v3.1 and later +were done by Martin Buchholz, Steve Baur, and Hrvoje Niksic. + + Corrections to the original GNU Emacs Lisp Reference Manual were +supplied by Karl Berry, Jim Blandy, Bard Bloom, Stephane Boucher, David +Boyes, Alan Carroll, Richard Davis, Lawrence R. Dodd, Peter Doornbosch, +David A. Duff, Chris Eich, Beverly Erlebacher, David Eckelkamp, Ralf +Fassel, Eirik Fuller, Stephen Gildea, Bob Glickstein, Eric Hanchrow, +George Hartzell, Nathan Hess, Masayuki Ida, Dan Jacobson, Jak Kirman, +Bob Knighten, Frederick M. Korz, Joe Lammens, Glenn M. Lewis, K. Richard +Magill, Brian Marick, Roland McGrath, Skip Montanaro, John Gardiner +Myers, Thomas A. Peterson, Francesco Potorti, Friedrich Pukelsheim, +Arnold D. Robbins, Raul Rockwell, Per Starback, Shinichirou Sugou, Kimmo +Suominen, Edward Tharp, Bill Trost, Rickard Westman, Jean White, Matthew +Wilding, Carl Witty, Dale Worley, Rusty Wright, and David D. Zuhn. + + +File: lispref.info, Node: Packaging, Next: Lisp Data Types, Prev: Introduction, Up: Top + +The XEmacs Packaging System +*************************** + +The XEmacs distribution, starting with version 21, comes only with a +very basic set of built-in modes and libraries. Most of the libraries +that were part of the distribution of earlier versions of XEmacs are now +available separately. The user as well as the system administrator can +choose which packages to install; the actual installation process is +easy. This gives an installer the ability to tailor an XEmacs +installation for local needs with safe removal of unnecessary code. + + This chapter describes how to package Lisp libraries for use with the +XEmacs Packaging System. + + _Please note carefully_ that the term "package" as used in XEmacs +refers to an aggregation of Lisp code and/or data distributed as a +unit. It does not, as it does in many Lisps, refer to a way of +creating separate name spaces. XEmacs has no facility for providing +separate name spaces. (If we ever do get separate name spaces, we'll +probably regret overloading the nomenclature in this way, but it's +become established.) + +* Menu: + +Introduction: +* Package Overview:: Lisp Libraries and Packages. + +Packaging Lisp Libraries: +* Package Terminology:: Basic stuff. +* Building Packages:: Turn packaged source into a tarball. +* Makefile Targets:: Package `Makefile' targets +* Local.rules File:: Tell the XEmacs Packaging System about your host. +* Creating Packages:: Tell the XEmacs Packaging System about your package. +* Documenting Packages:: Explain your package to users and hackers. + +Internals and Package Release Engineering: +* Issues:: + + +File: lispref.info, Node: Package Overview, Next: Package Terminology, Up: Packaging + +An overview of the XEmacs Packaging System +****************************************** + +The XEmacs Packaging System is a system for administering the +installation, upgrade, and removal of Lisp libraries. For the end +user, it provides facilities for determining availability of packages +and which versions at remote sites. It will download and automatically +install a package, ensuring that any old files from previous versions +of the package are removed first. By providing a standard set of +hierarchies for installation, it makes configuration of XEmacs simpler. +Furthermore, packages normally provide ancillary auto-autoloads and +custom-loads libraries, which are automatically detected and loaded by +XEmacs upon startup. This means that once installed, all facilities of +package, including autoloading the library upon invocation of a command +provided by the library and convenient configuration and customization, +are automatically available to the user. There is no need to add +autoloads or keybindings to in the init file, and structured +configuration of the package is available through the Customize system +even before the libraries are loaded. + + All of this convenience comes at a cost. The cost of administration +at the package level is negligible compared to the benefits, of course. +However, the requirement that XEmacs find and load auto-autoloads and +custom-loads libraries comes at a fairly large cost in startup time. In +order to reduce this cost, XEmacs imposes fairly strict conditions on +the structure of an installed package. + + Meeting these requirements, as well as simply providing the +auto-autoloads and the information about availability and so on does +impose some costs on the library maintainer. The XEmacs Packaging +System also provides structure and utilities to the library maintainer +to make these tasks easier. This manual documents the requirements and +the tools that the XEmacs Packaging System provides to ensure that a +package satisfies them. + +* Menu: + +* The User View:: +* The Library Maintainer View:: +* The Package Release Engineer View:: + + +File: lispref.info, Node: The User View, Next: The Library Maintainer View, Up: Package Overview + +The User View +============= + +*N.B.* Much of the discussion in this section undoubtedly belongs +elsewhere, *Note Packages: (xemacs)Packages. + + From the user's point of view, an XEmacs binary package is simply a +standard tarball (usually gzipped) containing Lisp sources, compiled +Lisp, documentation, and possibly data files or supporting executables. +The tarball is unpacked using standard tools such as GNU tar and gzip. +The package system does impose certain requirements for automatic +configuration to work. + + Here the main consideration is that the tarball "expects" to be +unpacked from the top of a package hierarchy. A "package hierarchy" is +basically an image of a classic Emacs "run-in-place" tree, with `lisp', +`etc', `info', `man', `lib-src', and `pkginfo' subdirectories of the +top. The `pkginfo' subdirectory is for use by the XEmacs Packaging +System administration tools, and currently contains a +`MANIFEST.PACKAGE-NAME' file for each package to ensure that no cruft +remains when a package is removed or updated. The `lisp', `etc', and +`lib-src' subdirectories are further subdivided, with a subdirectory +for each package. The `info' directory obeys the usual conventions. +_I.e._, the `info' directory is flat with a(n) (optional) `dir' file +and one (set of) info file(s) per package. The `man' subdirectory +typically contains documentation sources, separated by package. (It +does not contain `man(1)' pages, as Emacs provides very few of them.) + + There are several standard package hierarchies, and administrators +can configure others at build time, while users can configure others at +run time. The standard system hierarchies are all subdirectories of an +XEmacs installation root, typically `/usr/local/lib/xemacs/'. These +are the `xemacs-packages', `mule-packages', `infodock-packages', and +`site-packages' hierarchies. Each has the structure described above, +but the purposes differ. The `xemacs-packages' is the normal place for +installing "official" packages and many third-party libraries. +Unfortunately, it is not yet quite possible to read libraries +containing international characters with a non-Mule XEmacs, so such +libraries are sequestered in the `mule-packages' hierarchy. Some +packages are compatible only with the Infodock development environment, +and they will be installed in the `infodock-packages' hierarchy. The +`site-packages' hierarchy is for packages not distributed by +XEmacs.org, typically locally developed. + + Packages are in principle supposed to be XEmacs version-independent, +but if such dependencies are unavoidable, additional standard package +hierarchies may be installed under version directories, _e.g._ +`/usr/local/lib/xemacs-21.4.6/'. + + Users who do not have sufficient privilege to install packages in the +system hierarchies may install package hierarchies under `~/.xemacs'. +At present only the `xemacs-packages', `mule-packages', and +`site-packages' hierarchies are supported, but it might make sense to +extend this to support `infodock-packages' hierarchies in the future. + + The package hierarchies are not searched directly for libraries to be +loaded; this would be very costly. Instead, the hierarchies are ordered +according to certain rules, and searched for package lisp directories at +invocation. These directories are added to the general `load-path'. +As usual, it is `load-path' that is searched at run-time. This +approach is somewhat costly at initialization, but results in a very +"clean" `load-path'. + + The order of search can be changed at build time by specifying the +`--package-path' option to `configure', or at run-time by specifying +the `EMACSPACKAGEPATH' environment variable. *Note Packages: +(xemacs)Packages. + + The default order of search is hierarchically determined. First, the +roots are ordered. The "early" roots are the user-specific roots, +typically `~/.xemacs'. The "late" roots are the system roots, +typically `/usr/local/lib/xemacs-21.4.6' and `/usr/local/lib/xemacs', +in that order. All hierarchies for a given root are searched for +package Lisp directories, which are appended to `load-path' in the +order found. Then the search proceeds to the next root, whose results +will be appended to the `load-path' generated by previous roots. + + Second, the hierarchies below each root are searched in the order +`site-packages', `infodock-packages', `mule-packages', then +`xemacs-packages'. + + In each hierarchy there should be a `lisp' subdirectory, containing +directories named for the packages. Each package's Lisp libraries thus +are contained in a directory of the form ROOT/HIERARCHY/lisp/PACKAGE/. + + With such a complex search algorithm, the possibility of libraries +being shadowed by another library with the same name is quite real. +There are two considerations here. First, every XEmacs package +contains certain libraries with constant names. These are + +`_pkg.el' + Lisp code to inform the package administration system about the + package + +`auto-autoloads.el' + Lisp code to set up autoloaded functions and variables that may be + needed at load time + +`custom-load.el' + definitions of configuration variables for use with the Customize + system. + + They are special-cased, because the way they are used prevents +shadowing from being an issue. + + Second, it is possible that multiple copies of some library, or +different libraries with the same name, are installed in various places +in the hierarchies. To detect such shadows, use +`list-load-path-shadows'. + + Finally, note that most basic Emacs functionality, including most of +the Lisp API, is implemented in Lisp libraries. Because they use +internal reserved APIs that are subject to change according the needs +of the developers, these libraries are distributed with the XEmacs +binary, and are called "core Lisp libraries". Most core Lisp libraries +are "preloaded" into the Emacs binary and in normal usage are never +explicitly loaded. However, they can be explicitly loaded, and if so +they are searched on `load-path'. Furthermore, functions such as +`locate-library' will also search on the `load-path'. The searching +takes place under somewhat different rules from those used for packaged +Lisp. It is probably easiest to think of the package hierarchy +searching algorithm as receiving a `load-path' initialized to the core +Lisp directories. + + +File: lispref.info, Node: The Library Maintainer View, Next: The Package Release Engineer View, Prev: The User View, Up: Package Overview + +The Library Maintainer View +=========================== + +From the library maintainer's viewpoint, the advantages to the XEmacs +Packaging System stem from the convenience to the user of installation +and upgrade. Since an installed package automatically registers its +entry points via autoload and its configuration variables with the +Customize system, configuration FAQs are reduced. When it's easy to +upgrade, users learn to try `Tools | Packages | Update Installed +Packages' before posting a FAQ whose answer is "long since fixed, +please upgrade." + + This comes at some cost, as the library maintainer needs to arrange +that the package be installed in a directory structure that satisfies +the requirements of the XEmacs Packaging System. Autoload cookies and +defcustoms must also be added to existing libraries. The XEmacs +Packaging System provides infrastructure to assure that all of these +annoyances need only be dealt with once. The autoload cookies and +defcustoms are beyond the scope of this chapter, but most maintainers +of modern packages are already familiar with these mechanisms. + + The XEmacs Packaging System may be divided into the "infrastructure" +common to all packages, and the package-specific "control files". The +infrastructure supports global builds, installation, and generation of +the "sumo" bundles of packages, as well as generation of individual +packages. The package control files describe the structure of the +package's source tree and provide administrative information. + +* Menu: + +* Infrastructure:: Global Makefiles and common rules. +* Control Files:: Package-specific Makefiles and administrative files. +* Obtaining:: Obtaining the XEmacs Packaging System and required utilities. + + +File: lispref.info, Node: Infrastructure, Next: Control Files, Up: The Library Maintainer View + +Infrastructure +-------------- + +In order to get the greatest benefit from the XEmacs Packaging System, +a library maintainer should place the package sources in an appropriate +place in the XEmacs source package hierarchy, and arrange to have the +source package imported into the XEmacs CVS repository. (We realize +that the latter requirement can be quite burdensome. We are working on +ways to remove this requirement, but for the present it remains +necessary.) The library maintainer must also keep sources for any +packages his/her package requires. This requirement is somewhat +burdensome, but unlikely to be relaxed because of the implementation of +compilation of macros in Emacs Lisp. Macros cannot be called by +compiled Lisp (the macro expansion, which is always known at compile +time, is inlined), so the source of the macro must be loaded before +compiling the called function. + + The source package hierarchy may be rooted anywhere. The CVS module +is called "packages," so we will refer to the top directory of the +source package hierarchy as "the `packages' directory." The `packages' +directory contains two source subdirectories, `xemacs-packages' and +`mule-packages' (for convenience in segregating the packages which +depend on Mule, as they will cause load-time errors in a non-Mule +XEmacs). Each subdirectory contains many package source directories, +whose internal structure is not specified. That structure is left up +to the convenience of the library maintainers. The requirements on the +top directory of an individual package source tree are given below, +*Note Control Files::. + + The `packages' directory contains some auxiliary Lisp libraries used +in the compilation and packaging process. The content of these +libraries is of interest primarily to the packaging engineers, *Note +The Package Release Engineer View::. + + Finally, the `packages', `packages/xemacs-packages', and +`packages/mule-packages' directories contain `Makefile's and include +files to control the package creation process. The `Makefile's in +`packages/xemacs-packages' and `packages/mule-packages' simply define +the default sets of known packages and include `../iterate.rules', +which implements recursive building of all target packages. + + The `make' infrastructure in `packages' includes + +`Makefile' + controls building of individual packages, local installation, and + bundling of "sumo" tarballs + +`iterate.rules' + controls recursive builds of multiple packages + +`meta-iterate.rules' + This is used by higher-level subdirectories that do not directly + contain packages. Subdirectories directly containing packages + should use iterate.rules instead. + +`XEmacs.rules' + provides the rules for building and packaging. Included by all + package `Makefile's. + +`Local.rules' + provides local configuration, such as installation targets and + staging directories, as well as a number of kludges (many now + obsolete) required for building packages on the Windows platform. + +`Local.rules.template' + a template for Local.rules, liberally commented + +`Local.rules.mk' + consistency checking for `Local.rules', included by both the + top-level `Makefile' and by `XEmacs.rules'. + +`Local.rules.inc' + a file to `include' in package `Makefile's to be able to get at + variables in `Local.rules' _before_ including `XEmacs.rules'. + +`package-compile.el' + compile environment (_e.g._, load-path) setup. + + Of these, only `Local.rules' and `package-compile.el' need to be +modified by the library maintainer. The changes to Local.rules affect +only your environment. This should need to be done only once when +first preparing the source environment. The necessary modifications to +`package-compile.el' need to be done for each package and are discussed +in the next section, *Note Control Files::. + + +File: lispref.info, Node: Control Files, Next: Obtaining, Prev: Infrastructure, Up: The Library Maintainer View + +Control Files +------------- + +Each package source must contain a number of control files in the +top-level directory. These files in general can be created and then +ignored, except for a few variables that need to be updated when new +versions are released. In most cases even adding, renaming, and +removing library source files can be handled by generic rules. + + The package control files include + +`Makefile' + Must set a few `make' variables used by the administrative + utilities, and defines a couple of package-building targets to + depend on appropriate targets defined generically in + `XEmacs.rules'. It may also provide various variables and rules + to transform the source tree structure into that expected by the + run-time system. + +`package-info.in' + Provides a template for package information to be provided to the + administrative utilities. Static variables that are rarely changed + (such as the package's name) are entered as literals. Some + variables are generated by the build process (build dates and MD5 + checksums) and are automatically filled in. Finally, some + variables that change irregularly (dependences and even version + numbers) are set as `make' variables in the `Makefile'. + +`ChangeLog' + Not strictly required, but normally a ChangeLog will be added by + the XEmacs package maintainer if different from the upstream + maintainer. + +`_pkg.el' + Generated. Simply does a `package-provide' for the package. + +`auto-autoloads.el' + Generated. Read when XEmacs is initialized, and provides + autoloads for defuns and other forms in the sources that are + marked with an "autoload cookie" (`;;;###autoload'. + +`custom-loads.el' + Generated. Read when XEmacs is initialized, and informs the + Customize subsystem how to find the defcustom forms needed to + create Customization forms for the usre configuration variables of + the package. + + +File: lispref.info, Node: Obtaining, Prev: Control Files, Up: The Library Maintainer View + +Obtaining the XEmacs Packaging System and Required Utilities +------------------------------------------------------------ + +Currently both the infrastructure for creating XEmacs packages and the +package sources themselves are available only by CVS. See +`http://www.xemacs.org/Develop/cvsaccess.html' for more intformation. + + The XEmacs Packaging System currently requires GNU `make', and +XEmacs, to build packages. + + +File: lispref.info, Node: The Package Release Engineer View, Prev: The Library Maintainer View, Up: Package Overview + +The Package Release Engineer View +--------------------------------- + +The XEmacs Package Release Engineer is responsible for keeping the +system coherent. The changes to `packages/package-compile.el' and +`packages/xemacs-packages/Makefile' required to make the package +available to others, and for building SUMO tarballs, _etc_, are done by +the Package Release Engineer, not individual library maintainers. + + The Package Release Engineer also maintains assorted infrastructure +for actually making releases. These are generally available for +inspection in the `xemacs-builds' module in the CVS repository. + + +File: lispref.info, Node: Package Terminology, Next: Building Packages, Prev: Package Overview, Up: Packaging + +Package Terminology: +==================== + +Libraries and Packages +---------------------- + +A Lisp "library" is a single loadable file containing Lisp code. It +may be in source or byte-compiled form. A Lisp "package" is a set of +one or more libraries, usually related to each other in some way, +bundled with administrative information for convenient distribution. + +Package Flavors +--------------- + +There are two main flavors of packages. + +*Regular Packages* + A regular package is a set of Lisp libraries design to cooperate + with one another. A very complex example is Gnus. One may not in + general safely remove any of the component libraries. + +*Single-File Packages* + A single-file package is a collection of thematically related but + otherwise independent Lisp libraries. These libraries are bundled + together for convenience of the maintainers. Usually individual + libraries may be deleted at will without any loss of functionality + of other libraries in the package. However, we would recommend + that you follow this rule of thumb: "When in doubt, don't delete". + If it's really that big a deal, request that the maintainers + split the package into smaller aggregations. + +Package Distributions +--------------------- + +XEmacs Lisp packages are distributed in two ways. "Binary packages" +are used by system administrators and end users. They are packaged in a +form convenient for direct installation into an XEmacs package +hierarchy. "Source packages" are for developers and include all files +necessary for rebuilding byte-compiled lisp and creating tarballs for +distribution or installation. This is all of the package author's +source code plus all of the files necessary to build distribution +tarballs (Unix Tar format files, gzipped for space savings). +(Occasionally sources that are not relevant to XEmacs are usually +renamed to `file.upstream'.) + + Currently, source packages are only available via CVS. See + for details. + + The package distributions are also split according to major features +required in XEmacs to support them. At present there are "generic" +packages, which can be loaded by _any_ XEmacs, and "Mule" packages, +which _require_ Mule support or they will cause errors when loaded. +Note that there is no guarantee that a generic package will have any +useful functionality in a minimally configured XEmacs. As long as any +XEmacs can successfully load the package's libraries (perhaps given +other required Lisp libraries), it will be classified as generic. At +the present time only Mule packages need be treated specially, and even +those only if they contain multibyte characters. + + +File: lispref.info, Node: Building Packages, Next: Makefile Targets, Prev: Package Terminology, Up: Packaging + +Building Packages: +================== + +Currently, source packages are only available via anonymous CVS. See + for details of checking +out the `packages' module. + +Prerequisites for Building Source Packages +------------------------------------------ + +`GNU cp' + +`GNU install' + (or a BSD compatible install program). + +`GNU make' + (3.79 or later preferred). + +`makeinfo' + (4.2 from texinfo-4.2) + +`GNU tar' + (or equivalent). + +`GNU gzip' + (or equivalent). + +`A properly configured `Local.rules' file.' + *Note Local.rules File::. + + And of course, XEmacs, 21.0 or higher. + +What You Can Do With Source Packages +==================================== + +The packages CVS sources are most useful for creating XEmacs package +tarballs for installation into your own XEmacs installations or for +distributing to others. + + It should be noted that most of the package `Makefile's do _not_ +need to contain _any_ target rules. Everything is handled from the +`XEmacs.rules' file, located in the toplevel directory of the packages +source tree. + + +File: lispref.info, Node: Makefile Targets, Next: Local.rules File, Prev: Building Packages, Up: Packaging + +`Makefile' targets +****************** + +The following targets can be used when running `make' to build the +packages: + +`mostlyclean' + Removes any documentation files that have been processed by TeX. + +`clean' + Does a `mostlyclean', plus removes generated postscript and dvi + files. Also removes any generated .elc files, along with the + normal .elc files in the package and HTML and .info files. + +`distclean' + Use this when preparing a distribution. It kills anything that + can be rebuilt. + +`extraclean' + Does a `distclean' and also removes any backup files (`*~') and + `core' files. + +`package-info' + Creates the `package-info' file from the `package-info.in' and + writes an entry in the `package-index' file. + +`bindist' + Builds the package, including any Texinfo documentation (info + format), writes an entry into the `package-index' file and builds + a tarball of the package. Also writes an entry into + `setup-packages.ini' which is later used in the creation of + netinstaller's `setup.ini'. + +`install' + Builds and installs a package + +`install-only' + Doesn't build anything, just installs it. + +`autoloads' + Generate the package's `auto-autoloads.el' file. + +`binkit' + Creates the directories needed for installation and copies the + files there. Basically this is an alias for `install-only'. + +`html' + Builds the HTML versions of the documentation. + +`compile' + Does most of the work. Builds the elcs, infos at a minimum. + +The targets that most people would be interested in would be: +------------------------------------------------------------- + + * `all' + + * `bindist' + + * `html' + + * `install' + + * `install-only' + + * `clean' + + * `distclean' + + +File: lispref.info, Node: Local.rules File, Next: Creating Packages, Prev: Makefile Targets, Up: Packaging + +The Local.rules File: +===================== + +This file in `packages' provides the XEmacs Packaging System with +information about the local configuration and environment. To create +`Local.rules', simply copy `Local.rules.template' from that directory to +`Local.rules' and edit it to suit your needs. + + These are the variables in `Local.rules' that you may need to +provide values for: + +`XEMACS' + The name (and path if needed) of the XEmacs binary to use for + building the packages. The default is `xemacs'. + +`XEMACS_21_5' + This will enable some, as yet, unimplemented features in XEmacs + 21.5 and above. For now leave this blank (the default) regardless + of the XEmacs version you are using. + +`BUILD_WITHOUT_MULE' + Set this to `t' if you are using a non-Mule XEmacs. The default is + that this variable is not set (blank) which means to build _with_ + Mule. + +`XEMACS_NATIVE_NT' + Set this to `t' if you are using a native Microsoft Windows build + of XEmacs (not a Cygwin build) to build the packages. *N.B.* To + Windows users, you still need the Cygwin environment to actually + build the packages. + +`XEMACS_INSTALLED_PACKAGES_ROOT' + Set this to the root of where you want the packages to be + installed. Under this directory will hang `xemacs-packages' and + `mule-packages'. See NONMULE_INSTALLED_PACKAGES_ROOT and + MULE_INSTALLED_PACKAGES_ROOT. The default for this is + `/usr/local/lib/xemacs'. Which may not be what you want if you are + developing XEmacs. To quote the comments in + `Local.rules.template': + + If you are developing XEmacs, you probably don't want to + install the packages under /usr/local, which is where the + stable, released version of XEmacs goes. Instead, we suggest + a layout as described in the base README file of recent + versions of XEmacs. In a nutshell, we suggest you put your + source under /src/xemacs, and under this put the package + sources in package-src/, and the installed packages in + xemacs-packages/ and mule-packages/. If you do everything + this way, you might want to set things as follows: + + XEMACS_INSTALLED_PACKAGES_ROOT = ${XEMACS_PACKAGES_BASE}/.. + + which puts the xemacs-packages/ and mule-packages/ + directories as sisters of the package-src/ directory, and you + have to tell configure the location of the installed packages + using `-package-path', something like + + configure + -package-path=/src/xemacs/xemacs-packages;/src/xemacs/mule-packages + +`symlink' + The default is unset (blank). If you set this to `t' then `make + install' will create a "symlink farm" of the installed packages + under XEMACS_INSTALLED_PACKAGES_ROOT. Obviously, for this to + work, your system has to support symbolic links. This is as close + as you can get to "running in place" for the packages. + +`NONMULE_INSTALLED_PACKAGES_ROOT' + This is where the non-Mule packages get installed to. The default + is `${XEMACS_INSTALLED_PACKAGES_ROOT}/xemacs-packages'. + +`MULE_INSTALLED_PACKAGES_ROOT' + This is where the Mule packages get installed to. The default is + `${XEMACS_INSTALLED_PACKAGES_ROOT}/mule-packages'. + +`NONMULE_PACKAGES' + A whitespace separated list of non-Mule packages to build/install. + + NONMULE_PACKAGES = bbdb gnus xemacs-base prog-modes + + The value for this variable can also be the symbol + `xemacs-packages', which means to build/install _all_ of the + non-Mule packages. The default is `xemacs-packages'. + +`MULE_PACKAGES' + A whitespace separated list of Mule packages to build/install. + + MULE_PACKAGES = mule-base leim locale + + The value for this variable can also be the symbol + `mule-packages', which means to build/install _all_ of the Mule + packages. The default is `mule-packages'. + +`PACKAGE_INDEX' + The name of the package-index file. The default is `package-index' + and you probably don't need to worry about changing it. + +`INSTALL' + The path to a BSD compatible install program. The default is + `install -c'. + +`TAR' + The path to GNU/tar. The default is `tar'. + +`BZIP2' + The path to the bzip2 compression program. The default is unset + (blank). If this is set `.tar.bz2' archives will be built _in + addition to_ the `.tar.gz' archives. + +`EXCLUDES' + For things that you _don't_ want to go into the package tarballs. + It takes the same format as GNU/tar's `--exclude' option. The + default is: + + EXCLUDES = \ + --exclude 'CVS' \ + --exclude 'RCS' \ + --exclude 'SCCS' \ + --exclude '*~' \ + --exclude '*.orig' \ + --exclude '*.rej' \ + --exclude '.\#*' + +`VANILLA' + Set to the XEmacs command line option that forces running in + "vanilla" mode. The default is `-vanilla'. You wouldn't ever + need to alter this. + +`BATCH' + How to put XEmacs into "batch" mode. It also sets a couple of + other things and in the normal course of events you wouldn't need + to alter this from the default which is: + + BATCH = $(VANILLA) -batch -eval \ + '(setq stack-trace-on-error t \ + load-always-display-messages t \ + load-ignore-out-of-date-elc-files t \ + load-show-full-path-in-messages t)' + +`MAKEINFO' + The path to `makeinfo'. The default is `makeinfo' + +`INSTALL_HTML' + Set this to `t' if you want to install HTML versions of the Texinfo + documentation. The default is unset (blank). + +`TEXI2HTML' + The path to the program that can convert Texinfo source to HTML. + The default is `texi2html'. + +`TEXI2DVI' + The path to the program that can convert Texinfo source to DVI. + The default is `texi2dvi' + +`DVIPS' + The path to the program that can convert DVI to Postscript. The + default is `dvips' + +`TEXI2PDF' + The path to the program that can convert Texinfo source to PDF + format. The default is `texi2pdf'. + +`TEX' + The path to TeX. The default is `tex' + +`MSGFMT' + The path to msgfmt. The default is `msgfmt' + +`RCOPY' + The path to your copy command (GNU cp). The default is dependent + on whether or not SYMLINK is set (`t'). + + If SYMLINK is unset (blank), RCOPY's default is `cp -af'. If + SYMLINK is set (`t'), RCOPY's default is `cp --force --recursive + --symbolic-link'. + + It should be noted that in most cases the defaults should be fine. +Most people will probably only need to alter: + + * XEMACS_INSTALLED_PACKAGES_ROOT + + * NONMULE_INSTALLED_PACKAGES_ROOT + + * MULE_INSTALLED_PACKAGES_ROOT + + * NONMULE_PACKAGES + + * MULE_PACKAGES + + +File: lispref.info, Node: Creating Packages, Next: Documenting Packages, Prev: Local.rules File, Up: Packaging + +Creating Packages: +****************** + +Creating a package from an existing Lisp library is not very difficult. + + In addition to the Lisp libraries themselves, you need a *Note +package-info.in:: file and a simple *Note Makefile::. The rest is done +by `XEmacs.rules', part of the packaging system infrastructure. + +* Menu: + +* package-info.in:: package-info.in +* Makefile:: `Makefile' + + +File: lispref.info, Node: package-info.in, Next: Makefile, Up: Creating Packages + +package-info.in +*************** + +`package-info.in' contains information that gets injected into the +`package-index' file when `make bindist' is run. Here is a real world +example from the xemacs-base package (a description of each field +follows the example): + + (xemacs-base + (standards-version 1.1 + version VERSION + author-version AUTHOR_VERSION + date DATE + build-date BUILD_DATE + maintainer MAINTAINER + distribution xemacs + priority high + category CATEGORY + dump nil + description "Fundamental XEmacs support, you almost certainly need this." + filename FILENAME + md5sum MD5SUM + size SIZE + provides (add-log advice-preload advice annotations assoc case-table chistory comint-xemacs comint compile debug ebuff-menu echistory edmacro ehelp electric enriched env facemenu ffap helper imenu iso-syntax macros novice outline passwd pp regexp-opt regi ring shell skeleton sort thing time-stamp timezone tq xbm-button xpm-button) + requires (REQUIRES) + type regular + )) + +Description of the Fields in `package-info.in': +----------------------------------------------- + +`NAME' + The name of the package. In the case of the example it is + `xemacs-base'. + +`standards-version' + Part of the internal package infrastructure, its value should + always be `1.1'. Do not change this. + +`version' + This is the XEmacs package version number of the package. It is + set from the `Makefile' variable VERSION. This is something that + the XEmacs Package Release Engineer deals with so there is no need + for a package maintainer to touch it. In `package-info.in' just + put the place-marker, `VERSION' here. + +`author-version' + This is the package's internal, or `upstream' version number if it + has one. It is set from the `Makefile' variable AUTHOR_VERSION. + +`date' + This is the date of the last change made to the package. It is + auto-generated at build time, taken from the package's toplevel + `ChangeLog'. + +`build-date' + The date the package was built. It is auto-generated. + +`maintainer' + This is the name and email address of the package's maintainer. + It is taken from the `Makefile' variable MAINTAINER. + +`distribution' + An unused field, leave as `xemacs' + +`priority' + An unused field, can be any of `high', `medium', or `low'. + +`category' + The `category' of the package. It is taken from the `Makefile' + variable CATEGORY and can be either `standard' for non-Mule + packages, or `mule' for Mule packages. The is also provision for + `unsupported' in this field which would be for packages that + XEmacs.org do not distribute. + + *N.B.* As yet, the XEmacs Packaging System does _not_ support this + type of package. It will in the future. + +`dump' + Unused. Always `nil' + +`description' + A free form short description of the package. + +`filename' + The file name of the package's binary tarball. It is generated at + build time by `make bindist'. + +`md5sum' + The MD5 message digest of the package's binary tarball. Generated + at build time by `make bindist'. + +`size' + The size in bytes of the package's binary tarball. Generated at + build time. + +`provides' + A whitespace separated list of _all_ the features the package + provides. Surround the list with parens. + +`requires' + Taken from the `Makefile' variable REQUIRES. It is a list of all + the package's dependencies, including any macros and defstructs + that need to be inlined. + + `REQUIRES' cannot be correctly computed from the calls to + `require' in the package's library sources. `REQUIRES' is used to + ensure that all macro and defstruct definitions used by the + package are available at build time. This is not merely a matter + of efficiency, to get the expansions inlined. In fact, it is + _impossible_ to call a macro by name in byte-compiled Emacs Lisp + code. Thus, if the macro expansion is not inlined, the call will + result in an error at run-time! Thus, packages providing + libraries that would be loaded because of autoload definitions + must also be included. + +`type' + Can either be `regular' for a regular package, or `single-file' + for a single file package. + + *N.B.* This doesn't refer to the number of lisp files in a + package. A single-file package can have multiple lisp files in it. + *Note Package Terminology::. + + The fields in `package-info.in' that need to be changed directly are: + + * NAME + + * description + + * provides + + * type + + Everything else is either set from the appropriate `Makefile' +variable, is auto-generated at build time, or is static. + + +File: lispref.info, Node: Makefile, Prev: package-info.in, Up: Creating Packages + +`Makefile' +********** + +The `Makefile' is quite stylized. The idea is similar to an +`Imakefile' or an `automake' file: the complexity is hidden in generic +rules files, in this case the `XEmacs.rules' include file in the top +directory of the packages hierarchy. + + It is important to note that the XEmacs used to compile packages is +the bare minimum: it is called with the `-no-autoloads'. This means +that anything not dumped into XEmacs by default needs to be specified +in the `REQUIRES' variable (for packaged Lisp) or in some cases the +`PRELOADS' (autoloads used in libraries mentioned in `PRELOADS'). + + There isn't much to an XEmacs Packaging System `Makefile', basically +it just contains a few `Makefile' variables and that's it. See the +example. + + Here is a real world example, from the `build' package: + + # Makefile for build lisp code + + # 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. + + # For the time being, remove MULE_ELCS from the all dependencies if + # building without Mule. + + VERSION = 1.10 + AUTHOR_VERSION = 2.02 + MAINTAINER = Adrian Aichner + PACKAGE = build + PKG_TYPE = regular + REQUIRES = xemacs-base pcl-cvs dired w3 prog-modes + CATEGORY = standard + + ELCS = build.elc build-report.elc + + STANDARD_DOCS = t + + include ../../XEmacs.rules + + Most packages don't need any more than what you see above. It is +usually _not_ necessary to specify any special `Makefile' rules. +Everything is handled from the `*.rules' files in the toplevel of the +package source hierarchy. + + Of course, with that said, there are always exceptions to the rule. +If you think that your package will need some special `Makefile' +hackery contact the XEmacs developers . We +distribute over 100 packages so the chances are good that you won't be +the first to need such hackery and it is probably already catered for. + +`Makefile' Variables Explained: +------------------------------- + +A number of `make' variables are defined by the XEmacs Packaging +System. Some are required, others are optional. Of course your +`Makefile' may define other variables for private use, but you should +be careful not to choose names that conflict with variables defined and +used by the XEmacs Packaging System. + + The required variables are described in the table below. The +corresponding field names for `package-info.in', where relevant, are +given in parentheses. + +`VERSION' + (version) The version of the XEmacs package, a numeric literal (a + decimal fixed-point number with two-places of precision). The + only person who ever needs to touch this is the XEmacs Packages + Release Engineer. + +`AUTHOR_VERSION' + (author-version) The upstream author's version, an uninterpreted + literal. + +`MAINTAINER' + (maintainer) A literal containing the XEmacs package's maintainer + and his/her email address. + +`PACKAGE' + The name of the package, a literal + +`PKG_TYPE' + The type of package, a literal containing either `regular' for + regular packages, or `single-file' for single-file packages. This + should feed the `type' field in `package-info.in', but currently + it doesn't. + + *N.B.* `single-file' here does _not_ refer to the number of lisp + files in a package. *Note Package Terminology::. + +`CATEGORY' + (category) A literal, either `standard' or `mule'. The non-Mule + packages are `standard' and the Mule packages are, you guessed it, + `mule'. This field is used at package installation time as part of + the process of determining where a package should be installed to. + +`REQUIRES' + (requires) A list of packages required to correctly build this + package. + + Note that the usual form in `package-info.in' already has the + parentheses, so the `make' variable should be set to a + space-separated list of package names _not_ enclosed in + parentheses. + + The list is of _packages_, not _libraries_, as would ordinarily be + provided to the Lisp `require' function. + + `REQUIRES' cannot be correctly computed from the calls to + `require' in the package's library sources. `REQUIRES' is used to + ensure that all macro and defstruct definitions used by the + package are available at build time. This is not merely a matter + of efficiency, to get the expansions inlined. In fact, it is + _impossible_ to call a macro by name in byte-compiled Emacs Lisp + code. Thus, if the macro expansion is not inlined, the call will + result in an error at run-time! Thus, packages providing + libraries that would be loaded because of autoload definitions + must also be included. + +`ELCS' + The list of the byte-compiled Lisp files used by the package. + These files and their `.el' versions will be included in the binary + package. This variable determines which libraries will be + byte-compiled. These libraries are also deleted by `make clean'. + + Note there is no sanity-checking done on this variable. If you put + `.el' files in here, they will not be compiled and they _will_ be + deleted by `make clean'. You would surely be very distressed if + that happened, so be very careful. If this variable is left + empty, none of your Lisp code will be compiled or packaged. This + would be a less than amusing surprise, too. + + We don't consider this a feature, of course. Please do submit + code to do sanity checking to . + + Optional, but commonly used variables are explained below. + +`ELCS_1' + A list of extra byte-compiled Lisp files used by the package to be + installed in a subdirectory of the package's lisp directory. The + same care should be taken with this as with ELCS in regard to + `make clean'. + +`ELCS_1_DEST' + The name of the subdirectory for the ELCS_1 files to be installed + to. Be sure to include `$(PACKAGE)/' as part of the name. + + ELCS_1_DEST = $(PACKAGE)/extra + + Would put the ELCS_1 files for the package, `foo' into + `xemacs-packages/lisp/foo/extra/'. + +`EARLY_GENERATED_LISP' + For additional `.el' files that will be generated before any + byte-compiling happens. Use this for `autoload-type' files. You + must write `Makefile' rules to build these files. + +`GENERATED_LISP' + For additional `.el' files that will be generated at + byte-compilation time. You must write `Makefile' rules to build + these files. + +`PRELOADS' + This is used if you need to pass extra command line arguments to + XEmacs to build the package. For instance, a specification for + loading libraries containing macros before compiling the Lisp in + the package. This is spliced directly into the invocation of + XEmacs for byte-compilation, so it must contain the `-l' flag for + XEmacs: + + PRELOADS=-l ./apackage-macros.el -l ../bpackage/lisp/bpackage-macros.el + + Preloads are loaded before `package-compile.el', so the LOAD-PATH + is minimal. Therefore `PRELOADS' must specify a full path to + packaged Lisp. The base LOAD-PATH does include the core Lisp + directory, so core libraries are found. + +`AUTOLOAD_PATH' + The subdirectory in the package's source tree where the `.el' files + reside. This is where the `auto-autoloads.el' file will be placed. + + *N.B.* There is no need to use this variable if the `.el' files + are in the package's toplevel directory. AUTOLOAD_PATH defaults + to `.'. + +`PACKAGE_SUPPRESS' + Place calls to `package-suppress' here to indicate Lisp libraries + that should only be available to particular versions of XEmacs. + For example: + + PACKAGE_SUPPRESS = \ + (package-suppress 'xemacs-base \"regexp-opt\" '(emacs-version>= 21 5 11)) \ + (package-suppress 'xemacs-base \"easy-mmode\" '(emacs-version>= 21 5 11)) + + *N.B.* This feature has not yet been implemented in XEmacs yet. + It will appear in an upcoming version of XEmacs 21.5. + +`STANDARD_DOCS' + Set this to `t' if your package's Texinfo source file is located in + the package's toplevel directory _and_ is named `$(PACKAGE).texi'. + +`EXPLICIT_DOCS' + Use this to explicitly list Texinfo sources that _aren't_ in the + package's toplevel directory. For example: + + EXPLICIT_DOCS = texi/$(PACKAGE).texi + + See DOCS_TXI_EXTENSION and DOCS_TEXINFO_EXTENSION if you don't use + the `.texi' file extension on your Texinfo sources. + +`EXTRA_TEXI_FILES' + List here extra Texinfo source files needed to build your + documentation. Whatever is listed here is passed on to `makeinfo' + as a dependency. + +`EXTRA_HTML_FILES' + Use this to specify extra `.html' files to output. + +`DOCS_TEXINFO_EXTENSION' + Set this to `t' if your Texinfo source files have a `.texinfo' + extension. + +`DOCS_TXI_EXTENSION' + Set this to `t' if your Texinfo source files have a `.txi' + extension. + +`EXTRA_DOC_FILES' + Files listed here will be installed to `.../man/$(PACKAGE)/'. For + example, you might want to list TeX files or `.eps' files here. + +`EXTRA_SOURCES' + Other files (such as extra Lisp sources or an upstream `Makefile') + that are normally placed in the installed Lisp directory, but not + byte-compiled. These files are _preserved_ by the `clean' targets. + +`LIBSRC_FILES' + For files that need to be installed to `lib-src/$(PACKAGE)/'. If + the files listed here need to be built you will have to write + `Makefile' rules to do so. + +`DATA_FILES' + Any data files, such as pixmaps, READMEs, and ChangeLogs. These + must be paths relative to the root of the package's source tree. + These files will be copied to `$(DATA_DEST)' for installation. + Any directory component of the path for a file will be stripped, + so that the file ends up in `$(DATA_DEST)', not in a subdiredtory. + +`DATA_DEST' + The directory where the files in DATA_FILES are installed to. It + is a subdirectory of the installed `etc/' directory. Be sure to + prefix this value with `$(PACKAGE)', for example: + + DATA_DEST = $(PACKAGE)/foo + + Would put files into `.../etc/$(PACKAGE)/foo/'. + +`DATA_1_FILES ... DATA_35_FILES' + For data files that need to go into a different directory from + DATA_DEST. + +`DATA_1_DEST ... DATA_35_DEST' + The name of the subdirectory for files specified in DATA_N_FILES. + And like DATA_DEST, be sure to prefix `$(PACKAGE)' to the value of + these variables. + +`EXTRA_DEPENDENCIES' + For additional files to build that aren't appropriate to place in + any other `Makefile' variable. You will need to write `Makefile' + rules to build these files. + +`package-compile.el' +==================== + +The XEmacs Packaging System does not automatically become aware of your +package simply because there is a new subtree. If any package, +including your own, requires any of your files, it must be explicitly +added to the compile environment or loads/requires that search +load-path will fail. The changes that need to be made are + +*an entry in `package-directory-map'* + This tells the XEmacs Packaging System which distribution + (currently `xemacs-packages' or `mule-packages') your package is + found in. It then looks in the distribution subdirectory whose + name is the same as the package's. + +*an entry in the `cond' in `package-name-to-directory'* + This is optional; it is necessary only if you keep your Lisp code + somewhere other than the top-level directory of the package's + source tree, eg, in `packages/xemacs-packages/PACKAGE/lisp'. + + This only needs to be done once, when the package is first added to +the XEmacs Packaging System. (Well, when you randomly change the +subdirectory layout, too.) Your changes to `package-compile.el' must +be cleared and checked in by the XEmacs Package Release Engineer before +your package will build correctly from a fresh checkout. + + This is unfortunate; it works pretty well once set up, but can cause +confusion when first building a package in the XEmacs Packaging System +context. In particular, if the `package-directory-map' entry for a +required package, including the package itself, is not found, the +necessary requires will not be executed by `package-compile.el'. If +required functions are executed (under `eval-when-compile'), they won't +be found and the compile will fail. If required function is actually a +macro, the byte compiler will not recognize that, compile a function +call to the macro. This will cause a run-time error because the +byte-code interpreter does not know how to execute macros. (Macros can +always be expanded at compile-time, and this is more efficient.) + + If your package keeps some or all Lisp code somewhere other than the +top directory, then an entry in `package-name-to-directory' is also +necessary, or requires will fail, leading to the problems just +described. + + +File: lispref.info, Node: Documenting Packages, Next: Issues, Prev: Creating Packages, Up: Packaging + +Documenting Packages: +===================== + +Some random notes on documenting your package. + + Do write a Texinfo file. It's not that hard to do basically, and +even using the more advanced features of Texinfo soon become natural. +For a start, just grab the template `Samples/package.texi' from the +XEmacs Packaging System source tree, and drop your current README into +the Top node. At least this way your documentation will be accessible +from the standard Info readers. Next, try to add lots of +cross-referencing and logical markup, and then node structure. + + Address both end users and developer issues. You may not be the +maintainer forever. + + If you are maintaining a package that is part of the GNU Emacs +distribution, you'll likely find that you occasionally synchronize your +package with the GNU Emacs sources. When you synch a file, +conventionally you should place a comment just above the standard `;;; +Code' comment that looks like this: + + ;; Synched with: + ;; GNU Emacs 21.1, 2002-02-08, Stephen Turnbull + + This comment is a status flag; the ChangeLog doesn't really give the +same information. + + Do maintain a detailed ChangeLog. + + +File: lispref.info, Node: Issues, Prev: Documenting Packages, Up: Packaging + +Issues +====== + +To be completed. + + +File: lispref.info, Node: Lisp Data Types, Next: Numbers, Prev: Packaging, Up: Top + +Lisp Data Types +*************** + +A Lisp "object" is a piece of data used and manipulated by Lisp +programs. For our purposes, a "type" or "data type" is a set of +possible objects. + + Every object belongs to at least one type. Objects of the same type +have similar structures and may usually be used in the same contexts. +Types can overlap, and objects can belong to two or more types. +Consequently, we can ask whether an object belongs to a particular type, +but not for "the" type of an object. + + A few fundamental object types are built into XEmacs. These, from +which all other types are constructed, are called "primitive types". +Each object belongs to one and only one primitive type. These types +include "integer", "character" (starting with XEmacs 20.0), "float", +"cons", "symbol", "string", "vector", "bit-vector", "subr", +"compiled-function", "hash-table", "range-table", "char-table", +"weak-list", and several special types, such as "buffer", that are +related to editing. (*Note Editing Types::.) + + Each primitive type has a corresponding Lisp function that checks +whether an object is a member of that type. + + Note that Lisp is unlike many other languages in that Lisp objects +are "self-typing": the primitive type of the object is implicit in the +object itself. For example, if an object is a vector, nothing can treat +it as a number; Lisp knows it is a vector, not a number. + + In most languages, the programmer must declare the data type of each +variable, and the type is known by the compiler but not represented in +the data. Such type declarations do not exist in XEmacs Lisp. A Lisp +variable can have any type of value, and it remembers whatever value +you store in it, type and all. + + This chapter describes the purpose, printed representation, and read +syntax of each of the standard types in Emacs Lisp. Details on how to +use these types can be found in later chapters. + +* Menu: + +* Printed Representation:: How Lisp objects are represented as text. +* Comments:: Comments and their formatting conventions. +* Primitive Types:: List of all primitive types in XEmacs. +* Programming Types:: Types found in all Lisp systems. +* Editing Types:: Types specific to XEmacs. +* Window-System Types:: Types specific to windowing systems. +* Type Predicates:: Tests related to types. +* Equality Predicates:: Tests of equality between any two objects. + + +File: lispref.info, Node: Printed Representation, Next: Comments, Up: Lisp Data Types + +Printed Representation and Read Syntax +====================================== + +The "printed representation" of an object is the format of the output +generated by the Lisp printer (the function `prin1') for that object. +The "read syntax" of an object is the format of the input accepted by +the Lisp reader (the function `read') for that object. Most objects +have more than one possible read syntax. Some types of object have no +read syntax; except for these cases, the printed representation of an +object is also a read syntax for it. + + In other languages, an expression is text; it has no other form. In +Lisp, an expression is primarily a Lisp object and only secondarily the +text that is the object's read syntax. Often there is no need to +emphasize this distinction, but you must keep it in the back of your +mind, or you will occasionally be very confused. + + Every type has a printed representation. Some types have no read +syntax, since it may not make sense to enter objects of these types +directly in a Lisp program. For example, the buffer type does not have +a read syntax. Objects of these types are printed in "hash notation": +the characters `#<' followed by a descriptive string (typically the +type name followed by the name of the object), and closed with a +matching `>'. Hash notation cannot be read at all, so the Lisp reader +signals the error `invalid-read-syntax' whenever it encounters `#<'. + + (current-buffer) + => # + + When you evaluate an expression interactively, the Lisp interpreter +first reads the textual representation of it, producing a Lisp object, +and then evaluates that object (*note Evaluation::). However, +evaluation and reading are separate activities. Reading returns the +Lisp object represented by the text that is read; the object may or may +not be evaluated later. *Note Input Functions::, for a description of +`read', the basic function for reading objects. + + +File: lispref.info, Node: Comments, Next: Primitive Types, Prev: Printed Representation, Up: Lisp Data Types + +Comments +======== + +A "comment" is text that is written in a program only for the sake of +humans that read the program, and that has no effect on the meaning of +the program. In Lisp, a semicolon (`;') starts a comment if it is not +within a string or character constant. The comment continues to the +end of line. The Lisp reader discards comments; they do not become +part of the Lisp objects which represent the program within the Lisp +system. + + The `#@COUNT' construct, which skips the next COUNT characters, is +useful for program-generated comments containing binary data. The +XEmacs Lisp byte compiler uses this in its output files (*note Byte +Compilation::). It isn't meant for source files, however. + + *Note Comment Tips::, for conventions for formatting comments. + + +File: lispref.info, Node: Primitive Types, Next: Programming Types, Prev: Comments, Up: Lisp Data Types + +Primitive Types +=============== + +For reference, here is a list of all the primitive types that may exist +in XEmacs. Note that some of these types may not exist in some XEmacs +executables; that depends on the options that XEmacs was configured +with. + + * bit-vector + + * buffer + + * char-table + + * character + + * charset + + * coding-system + + * cons + + * color-instance + + * compiled-function + + * console + + * database + + * device + + * event + + * extent + + * face + + * float + + * font-instance + + * frame + + * glyph + + * hash-table + + * image-instance + + * integer + + * keymap + + * marker + + * process + + * range-table + + * specifier + + * string + + * subr + + * subwindow + + * symbol + + * toolbar-button + + * tooltalk-message + + * tooltalk-pattern + + * vector + + * weak-list + + * window + + * window-configuration + + * x-resource + + In addition, the following special types are created internally but +will never be seen by Lisp code. You may encounter them, however, if +you are debugging XEmacs. The printed representation of these objects +begins `# ?Q ?q => ?q + (char-int ?Q) => 81 + ;; Under XEmacs 19: + ?Q => 81 ?q => 113 + + You can use the same syntax for punctuation characters, but it is +often a good idea to add a `\' so that the Emacs commands for editing +Lisp code don't get confused. For example, `?\ ' is the way to write +the space character. If the character is `\', you _must_ use a second +`\' to quote it: `?\\'. XEmacs 20 always prints punctuation characters +with a `\' in front of them, to avoid confusion. + + You can express the characters Control-g, backspace, tab, newline, +vertical tab, formfeed, return, and escape as `?\a', `?\b', `?\t', +`?\n', `?\v', `?\f', `?\r', `?\e', respectively. Their character codes +are 7, 8, 9, 10, 11, 12, 13, and 27 in decimal. Thus, + + ;; Under XEmacs 20: + ?\a => ?\^G ; `C-g' + (char-int ?\a) => 7 + ?\b => ?\^H ; backspace, , `C-h' + (char-int ?\b) => 8 + ?\t => ?\t ; tab, , `C-i' + (char-int ?\t) => 9 + ?\n => ?\n ; newline, , `C-j' + ?\v => ?\^K ; vertical tab, `C-k' + ?\f => ?\^L ; formfeed character, `C-l' + ?\r => ?\r ; carriage return, , `C-m' + ?\e => ?\^[ ; escape character, , `C-[' + ?\\ => ?\\ ; backslash character, `\' + ;; Under XEmacs 19: + ?\a => 7 ; `C-g' + ?\b => 8 ; backspace, , `C-h' + ?\t => 9 ; tab, , `C-i' + ?\n => 10 ; newline, , `C-j' + ?\v => 11 ; vertical tab, `C-k' + ?\f => 12 ; formfeed character, `C-l' + ?\r => 13 ; carriage return, , `C-m' + ?\e => 27 ; escape character, , `C-[' + ?\\ => 92 ; backslash character, `\' + + These sequences which start with backslash are also known as "escape +sequences", because backslash plays the role of an escape character; +this usage has nothing to do with the character . + + Control characters may be represented using yet another read syntax. +This consists of a question mark followed by a backslash, caret, and the +corresponding non-control character, in either upper or lower case. For +example, both `?\^I' and `?\^i' are valid read syntax for the character +`C-i', the character whose value is 9. + + Instead of the `^', you can use `C-'; thus, `?\C-i' is equivalent to +`?\^I' and to `?\^i': + + ;; Under XEmacs 20: + ?\^I => ?\t ?\C-I => ?\t + (char-int ?\^I) => 9 + ;; Under XEmacs 19: + ?\^I => 9 ?\C-I => 9 + + There is also a character read syntax beginning with `\M-'. This +sets the high bit of the character code (same as adding 128 to the +character code). For example, `?\M-A' stands for the character with +character code 193, or 128 plus 65. You should _not_ use this syntax +in your programs. It is a holdover of yet another confoundance disease +from earlier Emacsen. (This was used to represent keyboard input with +the key set, thus the `M'; however, it conflicts with the +legitimate ISO-8859-1 interpretation of the character code. For +example, character code 193 is a lowercase `a' with an acute accent, in +ISO-8859-1.) + + Finally, the most general read syntax consists of a question mark +followed by a backslash and the character code in octal (up to three +octal digits); thus, `?\101' for the character `A', `?\001' for the +character `C-a', and `?\002' for the character `C-b'. Although this +syntax can represent any ASCII character, it is preferred only when the +precise octal value is more important than the ASCII representation. + + ;; Under XEmacs 20: + ?\012 => ?\n ?\n => ?\n ?\C-j => ?\n + ?\101 => ?A ?A => ?A + ;; Under XEmacs 19: + ?\012 => 10 ?\n => 10 ?\C-j => 10 + ?\101 => 65 ?A => 65 + + A backslash is allowed, and harmless, preceding any character without +a special escape meaning; thus, `?\+' is equivalent to `?+'. There is +no reason to add a backslash before most characters. However, you +should add a backslash before any of the characters `()\|;'`"#.,' to +avoid confusing the Emacs commands for editing Lisp code. Also add a +backslash before whitespace characters such as space, tab, newline and +formfeed. However, it is cleaner to use one of the easily readable +escape sequences, such as `\t', instead of an actual whitespace +character such as a tab. + + +File: lispref.info, Node: Symbol Type, Next: Sequence Type, Prev: Character Type, Up: Programming Types + +Symbol Type +----------- + +A "symbol" in XEmacs Lisp is an object with a name. The symbol name +serves as the printed representation of the symbol. In ordinary use, +the name is unique--no two symbols have the same name. + + A symbol can serve as a variable, as a function name, or to hold a +property list. Or it may serve only to be distinct from all other Lisp +objects, so that its presence in a data structure may be recognized +reliably. In a given context, usually only one of these uses is +intended. But you can use one symbol in all of these ways, +independently. + + A symbol name can contain any characters whatever. Most symbol names +are written with letters, digits, and the punctuation characters +`-+=*/'. Such names require no special punctuation; the characters of +the name suffice as long as the name does not look like a number. (If +it does, write a `\' at the beginning of the name to force +interpretation as a symbol.) The characters `_~!@$%^&:<>{}' are less +often used but also require no special punctuation. Any other +characters may be included in a symbol's name by escaping them with a +backslash. In contrast to its use in strings, however, a backslash in +the name of a symbol simply quotes the single character that follows the +backslash. For example, in a string, `\t' represents a tab character; +in the name of a symbol, however, `\t' merely quotes the letter `t'. +To have a symbol with a tab character in its name, you must actually +use a tab (preceded with a backslash). But it's rare to do such a +thing. + + Common Lisp note: In Common Lisp, lower case letters are always + "folded" to upper case, unless they are explicitly escaped. In + Emacs Lisp, upper case and lower case letters are distinct. + + Here are several examples of symbol names. Note that the `+' in the +fifth example is escaped to prevent it from being read as a number. +This is not necessary in the sixth example because the rest of the name +makes it invalid as a number. + + foo ; A symbol named `foo'. + FOO ; A symbol named `FOO', different from `foo'. + char-to-string ; A symbol named `char-to-string'. + 1+ ; A symbol named `1+' + ; (not `+1', which is an integer). + \+1 ; A symbol named `+1' + ; (not a very readable name). + \(*\ 1\ 2\) ; A symbol named `(* 1 2)' (a worse name). + +-*/_~!@$%^&=:<>{} ; A symbol named `+-*/_~!@$%^&=:<>{}'. + ; These characters need not be escaped. + + +File: lispref.info, Node: Sequence Type, Next: Cons Cell Type, Prev: Symbol Type, Up: Programming Types + +Sequence Types +-------------- + +A "sequence" is a Lisp object that represents an ordered set of +elements. There are two kinds of sequence in XEmacs Lisp, lists and +arrays. Thus, an object of type list or of type array is also +considered a sequence. + + Arrays are further subdivided into strings, vectors, and bit vectors. +Vectors can hold elements of any type, but string elements must be +characters, and bit vector elements must be either 0 or 1. However, the +characters in a string can have extents (*note Extents::) and text +properties (*note Text Properties::) like characters in a buffer; +vectors do not support extents or text properties even when their +elements happen to be characters. + + Lists, strings, vectors, and bit vectors are different, but they have +important similarities. For example, all have a length L, and all have +elements which can be indexed from zero to L minus one. Also, several +functions, called sequence functions, accept any kind of sequence. For +example, the function `elt' can be used to extract an element of a +sequence, given its index. *Note Sequences Arrays Vectors::. + + It is impossible to read the same sequence twice, since sequences are +always created anew upon reading. If you read the read syntax for a +sequence twice, you get two sequences with equal contents. There is one +exception: the empty list `()' always stands for the same object, `nil'. + + +File: lispref.info, Node: Cons Cell Type, Next: Array Type, Prev: Sequence Type, Up: Programming Types + +Cons Cell and List Types +------------------------ + +A "cons cell" is an object comprising two pointers named the CAR and +the CDR. Each of them can point to any Lisp object. + + A "list" is a series of cons cells, linked together so that the CDR +of each cons cell points either to another cons cell or to the empty +list. *Note Lists::, for functions that work on lists. Because most +cons cells are used as part of lists, the phrase "list structure" has +come to refer to any structure made out of cons cells. + + The names CAR and CDR have only historical meaning now. The +original Lisp implementation ran on an IBM 704 computer which divided +words into two parts, called the "address" part and the "decrement"; +CAR was an instruction to extract the contents of the address part of a +register, and CDR an instruction to extract the contents of the +decrement. By contrast, "cons cells" are named for the function `cons' +that creates them, which in turn is named for its purpose, the +construction of cells. + + Because cons cells are so central to Lisp, we also have a word for +"an object which is not a cons cell". These objects are called "atoms". + + The read syntax and printed representation for lists are identical, +and consist of a left parenthesis, an arbitrary number of elements, and +a right parenthesis. + + Upon reading, each object inside the parentheses becomes an element +of the list. That is, a cons cell is made for each element. The CAR +of the cons cell points to the element, and its CDR points to the next +cons cell of the list, which holds the next element in the list. The +CDR of the last cons cell is set to point to `nil'. + + A list can be illustrated by a diagram in which the cons cells are +shown as pairs of boxes. (The Lisp reader cannot read such an +illustration; unlike the textual notation, which can be understood by +both humans and computers, the box illustrations can be understood only +by humans.) The following represents the three-element list `(rose +violet buttercup)': + + ___ ___ ___ ___ ___ ___ + |___|___|--> |___|___|--> |___|___|--> nil + | | | + | | | + --> rose --> violet --> buttercup + + In this diagram, each box represents a slot that can refer to any +Lisp object. Each pair of boxes represents a cons cell. Each arrow is +a reference to a Lisp object, either an atom or another cons cell. + + In this example, the first box, the CAR of the first cons cell, +refers to or "contains" `rose' (a symbol). The second box, the CDR of +the first cons cell, refers to the next pair of boxes, the second cons +cell. The CAR of the second cons cell refers to `violet' and the CDR +refers to the third cons cell. The CDR of the third (and last) cons +cell refers to `nil'. + + Here is another diagram of the same list, `(rose violet buttercup)', +sketched in a different manner: + + --------------- ---------------- ------------------- + | car | cdr | | car | cdr | | car | cdr | + | rose | o-------->| violet | o-------->| buttercup | nil | + | | | | | | | | | + --------------- ---------------- ------------------- + + A list with no elements in it is the "empty list"; it is identical +to the symbol `nil'. In other words, `nil' is both a symbol and a list. + + Here are examples of lists written in Lisp syntax: + + (A 2 "A") ; A list of three elements. + () ; A list of no elements (the empty list). + nil ; A list of no elements (the empty list). + ("A ()") ; A list of one element: the string `"A ()"'. + (A ()) ; A list of two elements: `A' and the empty list. + (A nil) ; Equivalent to the previous. + ((A B C)) ; A list of one element + ; (which is a list of three elements). + + Here is the list `(A ())', or equivalently `(A nil)', depicted with +boxes and arrows: + + ___ ___ ___ ___ + |___|___|--> |___|___|--> nil + | | + | | + --> A --> nil + +* Menu: + +* Dotted Pair Notation:: An alternative syntax for lists. +* Association List Type:: A specially constructed list. + + +File: lispref.info, Node: Dotted Pair Notation, Next: Association List Type, Up: Cons Cell Type + +Dotted Pair Notation +.................... + +"Dotted pair notation" is an alternative syntax for cons cells that +represents the CAR and CDR explicitly. In this syntax, `(A . B)' +stands for a cons cell whose CAR is the object A, and whose CDR is the +object B. Dotted pair notation is therefore more general than list +syntax. In the dotted pair notation, the list `(1 2 3)' is written as +`(1 . (2 . (3 . nil)))'. For `nil'-terminated lists, the two +notations produce the same result, but list notation is usually clearer +and more convenient when it is applicable. When printing a list, the +dotted pair notation is only used if the CDR of a cell is not a list. + + Here's how box notation can illustrate dotted pairs. This example +shows the pair `(rose . violet)': + + ___ ___ + |___|___|--> violet + | + | + --> rose + + Dotted pair notation can be combined with list notation to represent +a chain of cons cells with a non-`nil' final CDR. For example, `(rose +violet . buttercup)' is equivalent to `(rose . (violet . buttercup))'. +The object looks like this: + + ___ ___ ___ ___ + |___|___|--> |___|___|--> buttercup + | | + | | + --> rose --> violet + + These diagrams make it evident why `(rose . violet . buttercup)' is +invalid syntax; it would require a cons cell that has three parts +rather than two. + + The list `(rose violet)' is equivalent to `(rose . (violet))' and +looks like this: + + ___ ___ ___ ___ + |___|___|--> |___|___|--> nil + | | + | | + --> rose --> violet + + Similarly, the three-element list `(rose violet buttercup)' is +equivalent to `(rose . (violet . (buttercup)))'. It looks like this: + + ___ ___ ___ ___ ___ ___ + |___|___|--> |___|___|--> |___|___|--> nil + | | | + | | | + --> rose --> violet --> buttercup + + +File: lispref.info, Node: Association List Type, Prev: Dotted Pair Notation, Up: Cons Cell Type + +Association List Type +..................... + +An "association list" or "alist" is a specially-constructed list whose +elements are cons cells. In each element, the CAR is considered a +"key", and the CDR is considered an "associated value". (In some +cases, the associated value is stored in the CAR of the CDR.) +Association lists are often used as stacks, since it is easy to add or +remove associations at the front of the list. + + For example, + + (setq alist-of-colors + '((rose . red) (lily . white) (buttercup . yellow))) + +sets the variable `alist-of-colors' to an alist of three elements. In +the first element, `rose' is the key and `red' is the value. + + *Note Association Lists::, for a further explanation of alists and +for functions that work on alists. + + +File: lispref.info, Node: Array Type, Next: String Type, Prev: Cons Cell Type, Up: Programming Types + +Array Type +---------- + +An "array" is composed of an arbitrary number of slots for referring to +other Lisp objects, arranged in a contiguous block of memory. +Accessing any element of an array takes the same amount of time. In +contrast, accessing an element of a list requires time proportional to +the position of the element in the list. (Elements at the end of a +list take longer to access than elements at the beginning of a list.) + + XEmacs defines three types of array, strings, vectors, and bit +vectors. A string is an array of characters, a vector is an array of +arbitrary objects, and a bit vector is an array of 1's and 0's. All are +one-dimensional. (Most other programming languages support +multidimensional arrays, but they are not essential; you can get the +same effect with an array of arrays.) Each type of array has its own +read syntax; see *Note String Type::, *Note Vector Type::, and *Note +Bit Vector Type::. + + An array may have any length up to the largest integer; but once +created, it has a fixed size. The first element of an array has index +zero, the second element has index 1, and so on. This is called +"zero-origin" indexing. For example, an array of four elements has +indices 0, 1, 2, and 3. + + The array type is contained in the sequence type and contains the +string type, the vector type, and the bit vector type. + + +File: lispref.info, Node: String Type, Next: Vector Type, Prev: Array Type, Up: Programming Types + +String Type +----------- + +A "string" is an array of characters. Strings are used for many +purposes in XEmacs, as can be expected in a text editor; for example, as +the names of Lisp symbols, as messages for the user, and to represent +text extracted from buffers. Strings in Lisp are constants: evaluation +of a string returns the same string. + + The read syntax for strings is a double-quote, an arbitrary number of +characters, and another double-quote, `"like this"'. The Lisp reader +accepts the same formats for reading the characters of a string as it +does for reading single characters (without the question mark that +begins a character literal). You can enter a nonprinting character such +as tab or `C-a' using the convenient escape sequences, like this: `"\t, +\C-a"'. You can include a double-quote in a string by preceding it +with a backslash; thus, `"\""' is a string containing just a single +double-quote character. (*Note Character Type::, for a description of +the read syntax for characters.) + + The printed representation of a string consists of a double-quote, +the characters it contains, and another double-quote. However, you must +escape any backslash or double-quote characters in the string with a +backslash, like this: `"this \" is an embedded quote"'. + + The newline character is not special in the read syntax for strings; +if you write a new line between the double-quotes, it becomes a +character in the string. But an escaped newline--one that is preceded +by `\'--does not become part of the string; i.e., the Lisp reader +ignores an escaped newline while reading a string. + + "It is useful to include newlines + in documentation strings, + but the newline is \ + ignored if escaped." + => "It is useful to include newlines + in documentation strings, + but the newline is ignored if escaped." + + A string can hold extents and properties of the text it contains, in +addition to the characters themselves. This enables programs that copy +text between strings and buffers to preserve the extents and properties +with no special effort. *Note Extents::, *Note Text Properties::. + + Note that FSF GNU Emacs has a special read and print syntax for +strings with text properties, but XEmacs does not currently implement +this. It was judged better not to include this in XEmacs because it +entails that `equal' return `nil' when passed a string with text +properties and the equivalent string without text properties, which is +often counter-intuitive. + + *Note Strings and Characters::, for functions that work on strings. + + +File: lispref.info, Node: Vector Type, Next: Bit Vector Type, Prev: String Type, Up: Programming Types + +Vector Type +----------- + +A "vector" is a one-dimensional array of elements of any type. It +takes a constant amount of time to access any element of a vector. (In +a list, the access time of an element is proportional to the distance of +the element from the beginning of the list.) + + The printed representation of a vector consists of a left square +bracket, the elements, and a right square bracket. This is also the +read syntax. Like numbers and strings, vectors are considered constants +for evaluation. + + [1 "two" (three)] ; A vector of three elements. + => [1 "two" (three)] + + *Note Vectors::, for functions that work with vectors. + + +File: lispref.info, Node: Bit Vector Type, Next: Function Type, Prev: Vector Type, Up: Programming Types + +Bit Vector Type +--------------- + +A "bit vector" is a one-dimensional array of 1's and 0's. It takes a +constant amount of time to access any element of a bit vector, as for +vectors. Bit vectors have an extremely compact internal representation +(one machine bit per element), which makes them ideal for keeping track +of unordered sets, large collections of boolean values, etc. + + The printed representation of a bit vector consists of `#*' followed +by the bits in the vector. This is also the read syntax. Like +numbers, strings, and vectors, bit vectors are considered constants for +evaluation. + + #*00101000 ; A bit vector of eight elements. + => #*00101000 + + *Note Bit Vectors::, for functions that work with bit vectors. + + +File: lispref.info, Node: Function Type, Next: Macro Type, Prev: Bit Vector Type, Up: Programming Types + +Function Type +------------- + +Just as functions in other programming languages are executable, "Lisp +function" objects are pieces of executable code. However, functions in +Lisp are primarily Lisp objects, and only secondarily the text which +represents them. These Lisp objects are lambda expressions: lists +whose first element is the symbol `lambda' (*note Lambda Expressions::). + + In most programming languages, it is impossible to have a function +without a name. In Lisp, a function has no intrinsic name. A lambda +expression is also called an "anonymous function" (*note Anonymous +Functions::). A named function in Lisp is actually a symbol with a +valid function in its function cell (*note Defining Functions::). + + Most of the time, functions are called when their names are written +in Lisp expressions in Lisp programs. However, you can construct or +obtain a function object at run time and then call it with the primitive +functions `funcall' and `apply'. *Note Calling Functions::. + + +File: lispref.info, Node: Macro Type, Next: Primitive Function Type, Prev: Function Type, Up: Programming Types + +Macro Type +---------- + +A "Lisp macro" is a user-defined construct that extends the Lisp +language. It is represented as an object much like a function, but with +different parameter-passing semantics. A Lisp macro has the form of a +list whose first element is the symbol `macro' and whose CDR is a Lisp +function object, including the `lambda' symbol. + + Lisp macro objects are usually defined with the built-in `defmacro' +function, but any list that begins with `macro' is a macro as far as +XEmacs is concerned. *Note Macros::, for an explanation of how to +write a macro. + + +File: lispref.info, Node: Primitive Function Type, Next: Compiled-Function Type, Prev: Macro Type, Up: Programming Types + +Primitive Function Type +----------------------- + +A "primitive function" is a function callable from Lisp but written in +the C programming language. Primitive functions are also called +"subrs" or "built-in functions". (The word "subr" is derived from +"subroutine".) Most primitive functions evaluate all their arguments +when they are called. A primitive function that does not evaluate all +its arguments is called a "special form" (*note Special Forms::). + + It does not matter to the caller of a function whether the function +is primitive. However, this does matter if you try to substitute a +function written in Lisp for a primitive of the same name. The reason +is that the primitive function may be called directly from C code. +Calls to the redefined function from Lisp will use the new definition, +but calls from C code may still use the built-in definition. + + The term "function" refers to all Emacs functions, whether written +in Lisp or C. *Note Function Type::, for information about the +functions written in Lisp. + + Primitive functions have no read syntax and print in hash notation +with the name of the subroutine. + + (symbol-function 'car) ; Access the function cell + ; of the symbol. + => # + (subrp (symbol-function 'car)) ; Is this a primitive function? + => t ; Yes. + + +File: lispref.info, Node: Compiled-Function Type, Next: Autoload Type, Prev: Primitive Function Type, Up: Programming Types + +Compiled-Function Type +---------------------- + +The byte compiler produces "compiled-function objects". The evaluator +handles this data type specially when it appears as a function to be +called. *Note Byte Compilation::, for information about the byte +compiler. + + The printed representation for a compiled-function object is normally +`#'. If `print-readably' is true, however, it is +`#[...]'. + + +File: lispref.info, Node: Autoload Type, Next: Char Table Type, Prev: Compiled-Function Type, Up: Programming Types + +Autoload Type +------------- + +An "autoload object" is a list whose first element is the symbol +`autoload'. It is stored as the function definition of a symbol as a +placeholder for the real definition; it says that the real definition +is found in a file of Lisp code that should be loaded when necessary. +The autoload object contains the name of the file, plus some other +information about the real definition. + + After the file has been loaded, the symbol should have a new function +definition that is not an autoload object. The new definition is then +called as if it had been there to begin with. From the user's point of +view, the function call works as expected, using the function definition +in the loaded file. + + An autoload object is usually created with the function `autoload', +which stores the object in the function cell of a symbol. *Note +Autoload::, for more details. + + +File: lispref.info, Node: Char Table Type, Next: Hash Table Type, Prev: Autoload Type, Up: Programming Types + +Char Table Type +--------------- + +(not yet documented) + + +File: lispref.info, Node: Hash Table Type, Next: Range Table Type, Prev: Char Table Type, Up: Programming Types + +Hash Table Type +--------------- + +A "hash table" is a table providing an arbitrary mapping from one Lisp +object to another, using an internal indexing method called "hashing". +Hash tables are very fast (much more efficient that using an +association list, when there are a large number of elements in the +table). + + Hash tables have a special read syntax beginning with +`#s(hash-table' (this is an example of "structure" read syntax. This +notation is also used for printing when `print-readably' is `t'. + + Otherwise they print in hash notation (The "hash" in "hash notation" +has nothing to do with the "hash" in "hash table"), giving the number +of elements, total space allocated for elements, and a unique number +assigned at the time the hash table was created. (Hash tables +automatically resize as necessary so there is no danger of running out +of space for elements.) + + (make-hash-table :size 50) + => # + + *Note Hash Tables::, for information on how to create and work with +hash tables. + + +File: lispref.info, Node: Range Table Type, Next: Weak List Type, Prev: Hash Table Type, Up: Programming Types + +Range Table Type +---------------- + +A "range table" is a table that maps from ranges of integers to +arbitrary Lisp objects. Range tables automatically combine overlapping +ranges that map to the same Lisp object, and operations are provided +for mapping over all of the ranges in a range table. + + Range tables have a special read syntax beginning with +`#s(range-table' (this is an example of "structure" read syntax, which +is also used for char tables and faces). + + (setq x (make-range-table)) + (put-range-table 20 50 'foo x) + (put-range-table 100 200 "bar" x) + x + => #s(range-table data ((20 50) foo (100 200) "bar")) + + *Note Range Tables::, for information on how to create and work with +range tables. + + +File: lispref.info, Node: Weak List Type, Prev: Range Table Type, Up: Programming Types + +Weak List Type +-------------- + +(not yet documented) + + +File: lispref.info, Node: Editing Types, Next: Window-System Types, Prev: Programming Types, Up: Lisp Data Types + +Editing Types +============= + +The types in the previous section are common to many Lisp dialects. +XEmacs Lisp provides several additional data types for purposes +connected with editing. + +* Menu: + +* Buffer Type:: The basic object of editing. +* Marker Type:: A position in a buffer. +* Extent Type:: A range in a buffer or string, maybe with properties. +* Window Type:: Buffers are displayed in windows. +* Frame Type:: Windows subdivide frames. +* Device Type:: Devices group all frames on a display. +* Console Type:: Consoles group all devices with the same keyboard. +* Window Configuration Type:: Recording the way a frame is subdivided. +* Event Type:: An interesting occurrence in the system. +* Process Type:: A process running on the underlying OS. +* Stream Type:: Receive or send characters. +* Keymap Type:: What function a keystroke invokes. +* Syntax Table Type:: What a character means. +* Display Table Type:: How display tables are represented. +* Database Type:: A connection to an external DBM or DB database. +* Charset Type:: A character set (e.g. all Kanji characters), + under XEmacs/MULE. +* Coding System Type:: An object encapsulating a way of converting between + different textual encodings, under XEmacs/MULE. +* ToolTalk Message Type:: A message, in the ToolTalk IPC protocol. +* ToolTalk Pattern Type:: A pattern, in the ToolTalk IPC protocol. + + +File: lispref.info, Node: Buffer Type, Next: Marker Type, Up: Editing Types + +Buffer Type +----------- + +A "buffer" is an object that holds text that can be edited (*note +Buffers::). Most buffers hold the contents of a disk file (*note +Files::) so they can be edited, but some are used for other purposes. +Most buffers are also meant to be seen by the user, and therefore +displayed, at some time, in a window (*note Windows::). But a buffer +need not be displayed in any window. + + The contents of a buffer are much like a string, but buffers are not +used like strings in XEmacs Lisp, and the available operations are +different. For example, insertion of text into a buffer is very +efficient, whereas "inserting" text into a string requires +concatenating substrings, and the result is an entirely new string +object. + + Each buffer has a designated position called "point" (*note +Positions::). At any time, one buffer is the "current buffer". Most +editing commands act on the contents of the current buffer in the +neighborhood of point. Many of the standard Emacs functions manipulate +or test the characters in the current buffer; a whole chapter in this +manual is devoted to describing these functions (*note Text::). + + Several other data structures are associated with each buffer: + + * a local syntax table (*note Syntax Tables::); + + * a local keymap (*note Keymaps::); + + * a local variable binding list (*note Buffer-Local Variables::); + + * a list of extents (*note Extents::); + + * and various other related properties. + +The local keymap and variable list contain entries that individually +override global bindings or values. These are used to customize the +behavior of programs in different buffers, without actually changing the +programs. + + A buffer may be "indirect", which means it shares the text of +another buffer. *Note Indirect Buffers::. + + Buffers have no read syntax. They print in hash notation, showing +the buffer name. + + (current-buffer) + => # + + +File: lispref.info, Node: Marker Type, Next: Extent Type, Prev: Buffer Type, Up: Editing Types + +Marker Type +----------- + +A "marker" denotes a position in a specific buffer. Markers therefore +have two components: one for the buffer, and one for the position. +Changes in the buffer's text automatically relocate the position value +as necessary to ensure that the marker always points between the same +two characters in the buffer. + + Markers have no read syntax. They print in hash notation, giving the +current character position and the name of the buffer. + + (point-marker) + => # + + *Note Markers::, for information on how to test, create, copy, and +move markers. + + +File: lispref.info, Node: Extent Type, Next: Window Type, Prev: Marker Type, Up: Editing Types + +Extent Type +----------- + +An "extent" specifies temporary alteration of the display appearance of +a part of a buffer (or string). It contains markers delimiting a range +of the buffer, plus a property list (a list whose elements are +alternating property names and values). Extents are used to present +parts of the buffer temporarily in a different display style. They +have no read syntax, and print in hash notation, giving the buffer name +and range of positions. + + Extents can exist over strings as well as buffers; the primary use +of this is to preserve extent and text property information as text is +copied from one buffer to another or between different parts of a +buffer. + + Extents have no read syntax. They print in hash notation, giving the +range of text they cover, the name of the buffer or string they are in, +the address in core, and a summary of some of the properties attached to +the extent. + + (extent-at (point)) + => # + + *Note Extents::, for how to create and use extents. + + Extents are used to implement text properties. *Note Text +Properties::. + + +File: lispref.info, Node: Window Type, Next: Frame Type, Prev: Extent Type, Up: Editing Types + +Window Type +----------- + +A "window" describes the portion of the frame that XEmacs uses to +display a buffer. (In standard window-system usage, a "window" is what +XEmacs calls a "frame"; XEmacs confusingly uses the term "window" to +refer to what is called a "pane" in standard window-system usage.) +Every window has one associated buffer, whose contents appear in the +window. By contrast, a given buffer may appear in one window, no +window, or several windows. + + Though many windows may exist simultaneously, at any time one window +is designated the "selected window". This is the window where the +cursor is (usually) displayed when XEmacs is ready for a command. The +selected window usually displays the current buffer, but this is not +necessarily the case. + + Windows are grouped on the screen into frames; each window belongs to +one and only one frame. *Note Frame Type::. + + Windows have no read syntax. They print in hash notation, giving the +name of the buffer being displayed and a unique number assigned at the +time the window was created. (This number can be useful because the +buffer displayed in any given window can change frequently.) + + (selected-window) + => # + + *Note Windows::, for a description of the functions that work on +windows. + + +File: lispref.info, Node: Frame Type, Next: Device Type, Prev: Window Type, Up: Editing Types + +Frame Type +---------- + +A FRAME is a rectangle on the screen (a "window" in standard +window-system terminology) that contains one or more non-overlapping +Emacs windows ("panes" in standard window-system terminology). A frame +initially contains a single main window (plus perhaps a minibuffer +window) which you can subdivide vertically or horizontally into smaller +windows. + + Frames have no read syntax. They print in hash notation, giving the +frame's type, name as used for resourcing, and a unique number assigned +at the time the frame was created. + + (selected-frame) + => # + + *Note Frames::, for a description of the functions that work on +frames. + + +File: lispref.info, Node: Device Type, Next: Console Type, Prev: Frame Type, Up: Editing Types + +Device Type +----------- + +A "device" represents a single display on which frames exist. +Normally, there is only one device object, but there may be more than +one if XEmacs is being run on a multi-headed display (e.g. an X server +with attached color and mono screens) or if XEmacs is simultaneously +driving frames attached to different consoles, e.g. an X display and a +TTY connection. + + Devices do not have a read syntax. They print in hash notation, +giving the device's type, connection name, and a unique number assigned +at the time the device was created. + + (selected-device) + => # + + *Note Consoles and Devices::, for a description of several functions +related to devices. + + +File: lispref.info, Node: Console Type, Next: Window Configuration Type, Prev: Device Type, Up: Editing Types + +Console Type +------------ + +A "console" represents a single keyboard to which devices (i.e. +displays on which frames exist) are connected. Normally, there is only +one console object, but there may be more than one if XEmacs is +simultaneously driving frames attached to different X servers and/or +TTY connections. (XEmacs is capable of driving multiple X and TTY +connections at the same time, and provides a robust mechanism for +handling the differing display capabilities of such heterogeneous +environments. A buffer with embedded glyphs and multiple fonts and +colors, for example, will display reasonably if it simultaneously +appears on a frame on a color X display, a frame on a mono X display, +and a frame on a TTY connection.) + + Consoles do not have a read syntax. They print in hash notation, +giving the console's type, connection name, and a unique number assigned +at the time the console was created. + + (selected-console) + => # + + *Note Consoles and Devices::, for a description of several functions +related to consoles. + + +File: lispref.info, Node: Window Configuration Type, Next: Event Type, Prev: Console Type, Up: Editing Types + +Window Configuration Type +------------------------- + +A "window configuration" stores information about the positions, sizes, +and contents of the windows in a frame, so you can recreate the same +arrangement of windows later. + + Window configurations do not have a read syntax. They print in hash +notation, giving a unique number assigned at the time the window +configuration was created. + + (current-window-configuration) + => # + + *Note Window Configurations::, for a description of several functions +related to window configurations. + + +File: lispref.info, Node: Event Type, Next: Process Type, Prev: Window Configuration Type, Up: Editing Types + +Event Type +---------- + +(not yet documented) + + +File: lispref.info, Node: Process Type, Next: Stream Type, Prev: Event Type, Up: Editing Types + +Process Type +------------ + +The word "process" usually means a running program. XEmacs itself runs +in a process of this sort. However, in XEmacs Lisp, a process is a +Lisp object that designates a subprocess created by the XEmacs process. +Programs such as shells, GDB, ftp, and compilers, running in +subprocesses of XEmacs, extend the capabilities of XEmacs. + + An Emacs subprocess takes textual input from Emacs and returns +textual output to Emacs for further manipulation. Emacs can also send +signals to the subprocess. + + Process objects have no read syntax. They print in hash notation, +giving the name of the process, its associated process ID, and the +current state of the process: + + (process-list) + => (#) + + *Note Processes::, for information about functions that create, +delete, return information about, send input or signals to, and receive +output from processes. + + +File: lispref.info, Node: Stream Type, Next: Keymap Type, Prev: Process Type, Up: Editing Types + +Stream Type +----------- + +A "stream" is an object that can be used as a source or sink for +characters--either to supply characters for input or to accept them as +output. Many different types can be used this way: markers, buffers, +strings, and functions. Most often, input streams (character sources) +obtain characters from the keyboard, a buffer, or a file, and output +streams (character sinks) send characters to a buffer, such as a +`*Help*' buffer, or to the echo area. + + The object `nil', in addition to its other meanings, may be used as +a stream. It stands for the value of the variable `standard-input' or +`standard-output'. Also, the object `t' as a stream specifies input +using the minibuffer (*note Minibuffers::) or output in the echo area +(*note The Echo Area::). + + Streams have no special printed representation or read syntax, and +print as whatever primitive type they are. + + *Note Read and Print::, for a description of functions related to +streams, including parsing and printing functions. + + +File: lispref.info, Node: Keymap Type, Next: Syntax Table Type, Prev: Stream Type, Up: Editing Types + +Keymap Type +----------- + +A "keymap" maps keys typed by the user to commands. This mapping +controls how the user's command input is executed. + + NOTE: In XEmacs, a keymap is a separate primitive type. In FSF GNU +Emacs, a keymap is actually a list whose CAR is the symbol `keymap'. + + *Note Keymaps::, for information about creating keymaps, handling +prefix keys, local as well as global keymaps, and changing key bindings. + + +File: lispref.info, Node: Syntax Table Type, Next: Display Table Type, Prev: Keymap Type, Up: Editing Types + +Syntax Table Type +----------------- + +Under XEmacs 20, a "syntax table" is a particular type of char table. +Under XEmacs 19, a syntax table a vector of 256 integers. In both +cases, each element defines how one character is interpreted when it +appears in a buffer. For example, in C mode (*note Major Modes::), the +`+' character is punctuation, but in Lisp mode it is a valid character +in a symbol. These modes specify different interpretations by changing +the syntax table entry for `+'. + + Syntax tables are used only for scanning text in buffers, not for +reading Lisp expressions. The table the Lisp interpreter uses to read +expressions is built into the XEmacs source code and cannot be changed; +thus, to change the list delimiters to be `{' and `}' instead of `(' +and `)' would be impossible. + + *Note Syntax Tables::, for details about syntax classes and how to +make and modify syntax tables. + + +File: lispref.info, Node: Display Table Type, Next: Database Type, Prev: Syntax Table Type, Up: Editing Types + +Display Table Type +------------------ + +A "display table" specifies how to display each character code. Each +buffer and each window can have its own display table. A display table +is actually a vector of length 256, although in XEmacs 20 this may +change to be a particular type of char table. *Note Display Tables::. + + +File: lispref.info, Node: Database Type, Next: Charset Type, Prev: Display Table Type, Up: Editing Types + +Database Type +------------- + +(not yet documented) + + +File: lispref.info, Node: Charset Type, Next: Coding System Type, Prev: Database Type, Up: Editing Types + +Charset Type +------------ + +(not yet documented) + + +File: lispref.info, Node: Coding System Type, Next: ToolTalk Message Type, Prev: Charset Type, Up: Editing Types + +Coding System Type +------------------ + +(not yet documented) + + +File: lispref.info, Node: ToolTalk Message Type, Next: ToolTalk Pattern Type, Prev: Coding System Type, Up: Editing Types + +ToolTalk Message Type +--------------------- + +(not yet documented) + + +File: lispref.info, Node: ToolTalk Pattern Type, Prev: ToolTalk Message Type, Up: Editing Types + +ToolTalk Pattern Type +--------------------- + +(not yet documented) + + +File: lispref.info, Node: Window-System Types, Next: Type Predicates, Prev: Editing Types, Up: Lisp Data Types + +Window-System Types +=================== + +XEmacs also has some types that represent objects such as faces +(collections of display characters), fonts, and pixmaps that are +commonly found in windowing systems. + +* Menu: + +* Face Type:: A collection of display characteristics. +* Glyph Type:: An image appearing in a buffer or elsewhere. +* Specifier Type:: A way of controlling display characteristics on + a per-buffer, -frame, -window, or -device level. +* Font Instance Type:: The way a font appears on a particular device. +* Color Instance Type:: The way a color appears on a particular device. +* Image Instance Type:: The way an image appears on a particular device. +* Toolbar Button Type:: An object representing a button in a toolbar. +* Subwindow Type:: An externally-controlled window-system window + appearing in a buffer. +* X Resource Type:: A miscellaneous X resource, if Epoch support was + compiled into XEmacs. + + +File: lispref.info, Node: Face Type, Next: Glyph Type, Up: Window-System Types + +Face Type +--------- + +(not yet documented) + + +File: lispref.info, Node: Glyph Type, Next: Specifier Type, Prev: Face Type, Up: Window-System Types + +Glyph Type +---------- + +(not yet documented) + + +File: lispref.info, Node: Specifier Type, Next: Font Instance Type, Prev: Glyph Type, Up: Window-System Types + +Specifier Type +-------------- + +(not yet documented) + + +File: lispref.info, Node: Font Instance Type, Next: Color Instance Type, Prev: Specifier Type, Up: Window-System Types + +Font Instance Type +------------------ + +(not yet documented) + + +File: lispref.info, Node: Color Instance Type, Next: Image Instance Type, Prev: Font Instance Type, Up: Window-System Types + +Color Instance Type +------------------- + +(not yet documented) + + +File: lispref.info, Node: Image Instance Type, Next: Toolbar Button Type, Prev: Color Instance Type, Up: Window-System Types + +Image Instance Type +------------------- + +(not yet documented) + + +File: lispref.info, Node: Toolbar Button Type, Next: Subwindow Type, Prev: Image Instance Type, Up: Window-System Types + +Toolbar Button Type +------------------- + +(not yet documented) + + +File: lispref.info, Node: Subwindow Type, Next: X Resource Type, Prev: Toolbar Button Type, Up: Window-System Types + +Subwindow Type +-------------- + +(not yet documented) + + +File: lispref.info, Node: X Resource Type, Prev: Subwindow Type, Up: Window-System Types + +X Resource Type +--------------- + +(not yet documented) + + +File: lispref.info, Node: Type Predicates, Next: Equality Predicates, Prev: Window-System Types, Up: Lisp Data Types + +Type Predicates +=============== + +The XEmacs Lisp interpreter itself does not perform type checking on +the actual arguments passed to functions when they are called. It could +not do so, since function arguments in Lisp do not have declared data +types, as they do in other programming languages. It is therefore up to +the individual function to test whether each actual argument belongs to +a type that the function can use. + + All built-in functions do check the types of their actual arguments +when appropriate, and signal a `wrong-type-argument' error if an +argument is of the wrong type. For example, here is what happens if you +pass an argument to `+' that it cannot handle: + + (+ 2 'a) + error--> Wrong type argument: integer-or-marker-p, a + + If you want your program to handle different types differently, you +must do explicit type checking. The most common way to check the type +of an object is to call a "type predicate" function. Emacs has a type +predicate for each type, as well as some predicates for combinations of +types. + + A type predicate function takes one argument; it returns `t' if the +argument belongs to the appropriate type, and `nil' otherwise. +Following a general Lisp convention for predicate functions, most type +predicates' names end with `p'. + + Here is an example which uses the predicates `listp' to check for a +list and `symbolp' to check for a symbol. + + (defun add-on (x) + (cond ((symbolp x) + ;; If X is a symbol, put it on LIST. + (setq list (cons x list))) + ((listp x) + ;; If X is a list, add its elements to LIST. + (setq list (append x list))) + (t + ;; We only handle symbols and lists. + (error "Invalid argument %s in add-on" x)))) + + Here is a table of predefined type predicates, in alphabetical order, +with references to further information. + +`annotationp' + *Note annotationp: Annotation Primitives. + +`arrayp' + *Note arrayp: Array Functions. + +`atom' + *Note atom: List-related Predicates. + +`bit-vector-p' + *Note bit-vector-p: Bit Vector Functions. + +`bitp' + *Note bitp: Bit Vector Functions. + +`boolean-specifier-p' + *Note boolean-specifier-p: Specifier Types. + +`buffer-glyph-p' + *Note buffer-glyph-p: Glyph Types. + +`buffer-live-p' + *Note buffer-live-p: Killing Buffers. + +`bufferp' + *Note bufferp: Buffer Basics. + +`button-event-p' + *Note button-event-p: Event Predicates. + +`button-press-event-p' + *Note button-press-event-p: Event Predicates. + +`button-release-event-p' + *Note button-release-event-p: Event Predicates. + +`case-table-p' + *Note case-table-p: Case Tables. + +`char-int-p' + *Note char-int-p: Character Codes. + +`char-or-char-int-p' + *Note char-or-char-int-p: Character Codes. + +`char-or-string-p' + *Note char-or-string-p: Predicates for Strings. + +`char-table-p' + *Note char-table-p: Char Tables. + +`characterp' + *Note characterp: Predicates for Characters. + +`color-instance-p' + *Note color-instance-p: Colors. + +`color-pixmap-image-instance-p' + *Note color-pixmap-image-instance-p: Image Instance Types. + +`color-specifier-p' + *Note color-specifier-p: Specifier Types. + +`commandp' + *Note commandp: Interactive Call. + +`compiled-function-p' + *Note compiled-function-p: Compiled-Function Type. + +`console-live-p' + *Note console-live-p: Connecting to a Console or Device. + +`consolep' + *Note consolep: Consoles and Devices. + +`consp' + *Note consp: List-related Predicates. + +`database-live-p' + *Note database-live-p: Connecting to a Database. + +`databasep' + *Note databasep: Databases. + +`device-live-p' + *Note device-live-p: Connecting to a Console or Device. + +`device-or-frame-p' + *Note device-or-frame-p: Basic Device Functions. + +`devicep' + *Note devicep: Consoles and Devices. + +`eval-event-p' + *Note eval-event-p: Event Predicates. + +`event-live-p' + *Note event-live-p: Event Predicates. + +`eventp' + *Note eventp: Events. + +`extent-live-p' + *Note extent-live-p: Creating and Modifying Extents. + +`extentp' + *Note extentp: Extents. + +`face-boolean-specifier-p' + *Note face-boolean-specifier-p: Specifier Types. + +`facep' + *Note facep: Basic Face Functions. + +`floatp' + *Note floatp: Predicates on Numbers. + +`font-instance-p' + *Note font-instance-p: Fonts. + +`font-specifier-p' + *Note font-specifier-p: Specifier Types. + +`frame-live-p' + *Note frame-live-p: Deleting Frames. + +`framep' + *Note framep: Frames. + +`functionp' + (not yet documented) + +`generic-specifier-p' + *Note generic-specifier-p: Specifier Types. + +`glyphp' + *Note glyphp: Glyphs. + +`hash-table-p' + *Note hash-table-p: Hash Tables. + +`icon-glyph-p' + *Note icon-glyph-p: Glyph Types. + +`image-instance-p' + *Note image-instance-p: Images. + +`image-specifier-p' + *Note image-specifier-p: Specifier Types. + +`integer-char-or-marker-p' + *Note integer-char-or-marker-p: Predicates on Markers. + +`integer-or-char-p' + *Note integer-or-char-p: Predicates for Characters. + +`integer-or-marker-p' + *Note integer-or-marker-p: Predicates on Markers. + +`integer-specifier-p' + *Note integer-specifier-p: Specifier Types. + +`integerp' + *Note integerp: Predicates on Numbers. + +`itimerp' + (not yet documented) + +`key-press-event-p' + *Note key-press-event-p: Event Predicates. + +`keymapp' + *Note keymapp: Creating Keymaps. + +`keywordp' + (not yet documented) + +`listp' + *Note listp: List-related Predicates. + +`markerp' + *Note markerp: Predicates on Markers. + +`misc-user-event-p' + *Note misc-user-event-p: Event Predicates. + +`mono-pixmap-image-instance-p' + *Note mono-pixmap-image-instance-p: Image Instance Types. + +`motion-event-p' + *Note motion-event-p: Event Predicates. + +`mouse-event-p' + *Note mouse-event-p: Event Predicates. + +`natnum-specifier-p' + *Note natnum-specifier-p: Specifier Types. + +`natnump' + *Note natnump: Predicates on Numbers. + +`nlistp' + *Note nlistp: List-related Predicates. + +`nothing-image-instance-p' + *Note nothing-image-instance-p: Image Instance Types. + +`number-char-or-marker-p' + *Note number-char-or-marker-p: Predicates on Markers. + +`number-or-marker-p' + *Note number-or-marker-p: Predicates on Markers. + +`numberp' + *Note numberp: Predicates on Numbers. + +`pointer-glyph-p' + *Note pointer-glyph-p: Glyph Types. + +`pointer-image-instance-p' + *Note pointer-image-instance-p: Image Instance Types. + +`process-event-p' + *Note process-event-p: Event Predicates. + +`processp' + *Note processp: Processes. + +`range-table-p' + *Note range-table-p: Range Tables. + +`ringp' + (not yet documented) + +`sequencep' + *Note sequencep: Sequence Functions. + +`specifierp' + *Note specifierp: Specifiers. + +`stringp' + *Note stringp: Predicates for Strings. + +`subrp' + *Note subrp: Function Cells. + +`subwindow-image-instance-p' + *Note subwindow-image-instance-p: Image Instance Types. + +`subwindowp' + *Note subwindowp: Subwindows. + +`symbolp' + *Note symbolp: Symbols. + +`syntax-table-p' + *Note syntax-table-p: Syntax Tables. + +`text-image-instance-p' + *Note text-image-instance-p: Image Instance Types. + +`timeout-event-p' + *Note timeout-event-p: Event Predicates. + +`toolbar-button-p' + *Note toolbar-button-p: Toolbar. + +`toolbar-specifier-p' + *Note toolbar-specifier-p: Toolbar. + +`user-variable-p' + *Note user-variable-p: Defining Variables. + +`vectorp' + *Note vectorp: Vectors. + +`weak-list-p' + *Note weak-list-p: Weak Lists. + +`window-configuration-p' + *Note window-configuration-p: Window Configurations. + +`window-live-p' + *Note window-live-p: Deleting Windows. + +`windowp' + *Note windowp: Basic Windows. + + The most general way to check the type of an object is to call the +function `type-of'. Recall that each object belongs to one and only +one primitive type; `type-of' tells you which one (*note Lisp Data +Types::). But `type-of' knows nothing about non-primitive types. In +most cases, it is more convenient to use type predicates than `type-of'. + + - Function: type-of object + This function returns a symbol naming the primitive type of + OBJECT. The value is one of `bit-vector', `buffer', `char-table', + `character', `charset', `coding-system', `cons', `color-instance', + `compiled-function', `console', `database', `device', `event', + `extent', `face', `float', `font-instance', `frame', `glyph', + `hash-table', `image-instance', `integer', `keymap', `marker', + `process', `range-table', `specifier', `string', `subr', + `subwindow', `symbol', `toolbar-button', `tooltalk-message', + `tooltalk-pattern', `vector', `weak-list', `window', + `window-configuration', or `x-resource'. + + (type-of 1) + => integer + (type-of 'nil) + => symbol + (type-of '()) ; `()' is `nil'. + => symbol + (type-of '(x)) + => cons + + +File: lispref.info, Node: Equality Predicates, Prev: Type Predicates, Up: Lisp Data Types + +Equality Predicates +=================== + +Here we describe two functions that test for equality between any two +objects. Other functions test equality between objects of specific +types, e.g., strings. For these predicates, see the appropriate chapter +describing the data type. + + - Function: eq object1 object2 + This function returns `t' if OBJECT1 and OBJECT2 are the same + object, `nil' otherwise. The "same object" means that a change in + one will be reflected by the same change in the other. + + `eq' returns `t' if OBJECT1 and OBJECT2 are integers with the same + value. Also, since symbol names are normally unique, if the + arguments are symbols with the same name, they are `eq'. For + other types (e.g., lists, vectors, strings), two arguments with + the same contents or elements are not necessarily `eq' to each + other: they are `eq' only if they are the same object. + + (The `make-symbol' function returns an uninterned symbol that is + not interned in the standard `obarray'. When uninterned symbols + are in use, symbol names are no longer unique. Distinct symbols + with the same name are not `eq'. *Note Creating Symbols::.) + + NOTE: Under XEmacs 19, characters are really just integers, and + thus characters and integers are `eq'. Under XEmacs 20, it was + necessary to preserve remnants of this in function such as `old-eq' + in order to maintain byte-code compatibility. Byte code compiled + under any Emacs 19 will automatically have calls to `eq' mapped to + `old-eq' when executed under XEmacs 20. + + (eq 'foo 'foo) + => t + + (eq 456 456) + => t + + (eq "asdf" "asdf") + => nil + + (eq '(1 (2 (3))) '(1 (2 (3)))) + => nil + + (setq foo '(1 (2 (3)))) + => (1 (2 (3))) + (eq foo foo) + => t + (eq foo '(1 (2 (3)))) + => nil + + (eq [(1 2) 3] [(1 2) 3]) + => nil + + (eq (point-marker) (point-marker)) + => nil + + + - Function: old-eq object1 object2 + This function exists under XEmacs 20 and is exactly like `eq' + except that it suffers from the char-int confoundance disease. In + other words, it returns `t' if given a character and the + equivalent integer, even though the objects are of different types! + You should _not_ ever call this function explicitly in your code. + However, be aware that all calls to `eq' in byte code compiled + under version 19 map to `old-eq' in XEmacs 20. (Likewise for + `old-equal', `old-memq', `old-member', `old-assq' and + `old-assoc'.) + + ;; Remember, this does not apply under XEmacs 19. + ?A + => ?A + (char-int ?A) + => 65 + (old-eq ?A 65) + => t ; Eek, we've been infected. + (eq ?A 65) + => nil ; We are still healthy. + + - Function: equal object1 object2 + This function returns `t' if OBJECT1 and OBJECT2 have equal + components, `nil' otherwise. Whereas `eq' tests if its arguments + are the same object, `equal' looks inside nonidentical arguments + to see if their elements are the same. So, if two objects are + `eq', they are `equal', but the converse is not always true. + + (equal 'foo 'foo) + => t + + (equal 456 456) + => t + + (equal "asdf" "asdf") + => t + (eq "asdf" "asdf") + => nil + + (equal '(1 (2 (3))) '(1 (2 (3)))) + => t + (eq '(1 (2 (3))) '(1 (2 (3)))) + => nil + + (equal [(1 2) 3] [(1 2) 3]) + => t + (eq [(1 2) 3] [(1 2) 3]) + => nil + + (equal (point-marker) (point-marker)) + => t + + (eq (point-marker) (point-marker)) + => nil + + Comparison of strings is case-sensitive. + + Note that in FSF GNU Emacs, comparison of strings takes into + account their text properties, and you have to use `string-equal' + if you want only the strings themselves compared. This difference + does not exist in XEmacs; `equal' and `string-equal' always return + the same value on the same strings. + + (equal "asdf" "ASDF") + => nil + + Two distinct buffers are never `equal', even if their contents are + the same. + + The test for equality is implemented recursively, and circular lists +may therefore cause infinite recursion (leading to an error). + + +File: lispref.info, Node: Numbers, Next: Strings and Characters, Prev: Lisp Data Types, Up: Top + +Numbers +******* + +XEmacs supports two numeric data types: "integers" and "floating point +numbers". Integers are whole numbers such as -3, 0, #b0111, #xFEED, +#o744. Their values are exact. The number prefixes `#b', `#o', and +`#x' are supported to represent numbers in binary, octal, and +hexadecimal notation (or radix). Floating point numbers are numbers +with fractional parts, such as -4.5, 0.0, or 2.71828. They can also be +expressed in exponential notation: 1.5e2 equals 150; in this example, +`e2' stands for ten to the second power, and is multiplied by 1.5. +Floating point values are not exact; they have a fixed, limited amount +of precision. + +* Menu: + +* Integer Basics:: Representation and range of integers. +* Float Basics:: Representation and range of floating point. +* Predicates on Numbers:: Testing f