help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] [RFC] Path improvements version 2


From: Paolo Bonzini
Subject: [Help-smalltalk] [RFC] Path improvements version 2
Date: Sat, 10 Feb 2007 13:18:17 +0100
User-agent: Thunderbird 1.5.0.9 (Macintosh/20061207)

This version mostly fixes bugs; I also tested that no traces of the DESTDIR remain in the image after installation.

Other changes:

- the `Directory userKernel' was renamed to `Directory userBase'

- the `local image' concept is changed to this definition: an image is local unless the kernel path is IMAGE-PATH/kernel. This is mostly irrelevant, it's only important to ensure that the system kernel files are overridden by files in ~/.st

- the .st/init.st file is still there for now

- a new option, --no-user-files, is added and used during the build.

I've committed this because it's already a good start, but I'm open to suggestions.

Paolo
 2007-02-06  Paolo Bonzini  <address@hidden>
 
        * kernel/Directory.st: Add #kernel and #userKernel, deprecate
        #systemKernel and #localKernel.
        * kernel/VFS.st: Adjust.
        * kernel/PkgLoader.st: Adjust.
        * kernel/SysDict.st: Add #imageLocal.

        * scripts/Finish.st: Get `old' file path from ImageFilePath.

        * libgst/dict.c: Remove KernelFileLocalPath.  Don't touch
        KernelFilePath on reload.  Export KernelFileUserPath.
        * libgst/lib.c: Add --image-directory and --kernel-directory.
        Add a struct loaded_file used to store files given on
        the command line.  Find path of user init/user pre/site
        pre files in init_paths, delete load_user_init_file and
        load_user_pre_image_file.  Call init_paths after parse_args.
        Rewrite find_kernel_file, place kernel override files
        in ~/.st too (if one needs per-image overrides they can
        use --kernel-directory).  Remove some variables that are
        now unused.  Simplify ok_to_load_binary as the new semantics
        remove the need for some checks.  Export the path to ~/.st in
        _gst_user_file_base_path.
        * libgst/lib.h: Export _gst_user_file_base_path.
        * libgst/sysdep.c: Canonicalize path in _gst_get_full_file_name.


M  configure.ac
M  doc/Makefile.am
M  doc/gst.texi
M  gst-package.in
M  ChangeLog
M  Makefile.am
M  NEWS
M  TODO
M  kernel/Directory.st
M  kernel/PkgLoader.st
M  kernel/SysDict.st
M  kernel/VFS.st
M  libgst/ChangeLog
M  scripts/Finish.st
M  libgst/lib.c
M  libgst/lib.h
M  libgst/dict.c
M  libgst/sysdep.c
M  tests/Makefile.am

* modified files

--- orig/Makefile.am
+++ mod/Makefile.am
@@ -127,9 +127,8 @@ gsticon.o: gsticon.ico
        echo ProgramIcon ICON `cygpath -w gsticon.ico` | windres -o gsticon.o
 
 gst.im: $(bin_PROGRAMS) $(srcdir)/kernel/stamp-classes
-       SMALLTALK_KERNEL="`cd $(srcdir)/kernel; pwd`" \
-       SMALLTALK_IMAGE="`pwd`" \
-         ./gst -iQ /dev/null
+       ./gst --no-user-files --kernel-dir="@abs_top_srcdir@/kernel" \
+         --image-dir="@abs_top_builddir@" -iQ /dev/null
 
 all-local:
 
@@ -167,21 +166,21 @@ dist-hook: gst-package
          -e "s/@\(NCURSES_DISABLED\)@/disabled-/" \
          -e "s/@\(VERSION\)@/@VERSION@/" \
          $(srcdir)/packages.xml.in > $(distdir)/packages.xml
-       SMALLTALK_IMAGE=$(distdir) \
-         ./gst-package --srcdir="$(srcdir)" --dist $(distdir)/packages.xml
+       ./gst-package --distdir=$(distdir) --srcdir="$(srcdir)" \
+         --dist $(distdir)/packages.xml
 
 # Build an image after installing the data; install-data runs after
 # install-exec, so the gst executable is already in bindir.
 install-data-hook: gst-package
        rm -f $(DESTDIR)$(pkgdatadir)/packages.xml
-       ./gst-package --srcdir="$(srcdir)" --no-load --destdir="$(DESTDIR)" 
packages.xml
+       ./gst-package --srcdir="$(srcdir)" --no-load --destdir="$(DESTDIR)" \
+         packages.xml
        srcdir=`cd $(srcdir) && pwd`; \
        cd $(DESTDIR)$(pkgdatadir); \
        rm -f gst.im; \
-       SMALLTALK_KERNEL="`pwd`/kernel" \
-       SMALLTALK_IMAGE="`pwd`" \
-         $(DESTDIR)$(bindir)/gst -f $$srcdir/scripts/Finish.st \
-           "$(DESTDIR)$(pkgdatadir)" "$(pkgdatadir)" $(MODULES)
+         $(DESTDIR)$(bindir)/gst --no-user-files -i \
+           --kernel-dir=kernel --image-dir=. \
+           -f $$srcdir/scripts/Finish.st "$(pkgdatadir)" $(MODULES)
 
 uninstall-local:: gst-package
        ./gst-package --uninstall --destdir="$(DESTDIR)" packages.xml


--- orig/NEWS
+++ mod/NEWS
@@ -2,17 +2,35 @@ List of user-visible changes in GNU Smal
 
 NEWS FROM 2.3.2 TO 2.4
 
-o   Startup time and quit time were improved widely (the time for running
-    a simple "Hello, World" program is about one fifth of 2.3.x).
+o   A different startup sequence is used which improves the possibility to
+    customize GNU Smalltalk, both site-wide and per-user.  The details are
+    in the manual, the main changes are these: the `.stinit' and `.stpre'
+    files are now named `.st/init.st' and `.st/pre.st'; files requested
+    with the `-K' command-line option are sought for in the `.st' directory
+    too (in the home directory); kernel files may be overridden by placing
+    them in `.st/kernel'; a site-wide customization file can be placed
+    in `/usr/local/share/smalltalk/site-pre.st'.
+
+    The kernel path is stored in the image and not changed when the image
+    is loaded.  In addition, `Directory systemKernel' and `Directory
+    localKernel' are not used anymore, and just return the same as
+    `Directory kernel'.
+
+    Finally, Smalltalk programs have access to the aforementioned `.st'
+    directory as `Directory userKernel' (name subject to change).  A
+    `packages.xml' file can be put there.
 
 o   Directory entries are passed to #allFilesMatching:do:'s block argument
     if they match aPattern.  As before, the function descends in all the
     directories, even those that do not match aPattern.
 
-o   The image is loaded using copy-on-write memory mapped files.  This means
-    that as long as a loaded object is not touched, the operating system
-    will map it to the same physical memory, for different copies of
-    the GNU Smalltalk virtual machine that loaded the same image.
+o   Image load uses copy-on-write memory mapped files.  This means that, as
+    long as a loaded object is not touched, the operating system will map
+    it to the same physical memory, for different copies of the GNU Smalltalk
+    virtual machine that loaded the same image.
+
+o   Startup time and quit time were improved widely (the time for running
+    a simple "Hello, World" program is about one fifth of 2.3.x).
 
 -----------------------------------------------------------------------------
 


--- orig/TODO
+++ mod/TODO
@@ -1,42 +1,25 @@
-* 2.2
+* 2.4
 
-** use intptr_t instead of long for SmallIntegers.  In general,
-use stdint.h/inttypes.h way more widely (with an automatically
-generated one, perusing Autoconf). (done)
+** implement SmallScript file-in?
 
-** use libffi to fix bugs in C call-outs (done)
+** use VFS to (re)implement packages?
 
-** remove logging and -s (done)
+** faster startup (done)
 
-** new bytecode set! (done)
+** restructure init/pre/kernel files (done)
 
-** shared library (done)
 
-** fix bitrot in JITter (done)
+* sometime
 
 ** some kind of sandboxing (partly done)
 
-** Java support (partly done)
-
-** fix debugging of JITted code (boring)
-
-** deprecate SMALLTALK_IMAGE and SMALLTALK_KERNEL in favor of
-two new options, --image-directory and --kernel-directory
-(harder than it looks)
-
-* sometime
-
 ** add check in/check out to the browser so that .st files remain
 in sync.  Maybe with CVS support (see Smalltalk/X).
 
 ** cute BlockClosure implementations
 
-** implement SmallScript file-in?
-
 ** port more software (Ref. Browser?)
 
-** use VFS to (re)implement packages?
-
 
 ----------------------------------------------------------------------
 


--- orig/configure.ac
+++ mod/configure.ac
@@ -206,7 +206,7 @@ AC_REPLACE_FUNCS(putenv strdup strerror 
        getdtablesize strstr ftruncate floorl ceill sqrtl frexpl ldexpl asinl \
        acosl atanl logl expl tanl sinl cosl truncl strsep strpbrk)
 AC_CHECK_FUNCS_ONCE(gethostname memcpy memmove sighold uname sbrk usleep lstat 
\
-       grantpt popen getrusage gettimeofday getcwd fork strchr \
+       grantpt popen getrusage gettimeofday getcwd fork strchr readlink \
        sigsetmask alarm select mprotect madvise nl_langinfo waitpid \
        setsid spawnl nanosleep pread pwrite)
 


--- orig/doc/Makefile.am
+++ mod/doc/Makefile.am
@@ -41,42 +41,26 @@ PUBLISHED_NAMESPACES = Smalltalk SystemE
 
 $(srcdir)/blox.texi: $(top_srcdir)/blox-tk/stamp-classes
        rm -f $(srcdir)/blox.texi
-       builddir=`pwd`; gst=$$builddir/../gst; gst_im=$$builddir/../gst.im; \
-       cd $(srcdir) && \
-         $$gst -I $$gst_im -f ../scripts/GenLibDoc.st \
-           BLOX BloxTK blox.texi Blox.st
+       cd $(srcdir) && @abs_top_builddir@/gst -I @abs_top_builddir@/gst.im \
+           -f ../scripts/GenLibDoc.st BLOX BloxTK blox.texi Blox.st
        test -f $(srcdir)/blox.texi && touch $(srcdir)/gst-libs.texi 
 
 $(srcdir)/tcp.texi: $(top_srcdir)/tcp/stamp-classes
        rm -f $(srcdir)/tcp.texi
-       builddir=`pwd`; gst=$$builddir/../gst; gst_im=$$builddir/../gst.im; \
-       cd $(srcdir) && \
-         $$gst -I $$gst_im -f ../scripts/GenLibDoc.st \
-           TCP TCP tcp.texi TCP.st
+       cd $(srcdir) && @abs_top_builddir@/gst -I @abs_top_builddir@/gst.im \
+           -f ../scripts/GenLibDoc.st TCP TCP tcp.texi TCP.st
        test -f $(srcdir)/tcp.texi && touch $(srcdir)/gst-libs.texi 
 
 $(srcdir)/i18n.texi: $(top_srcdir)/i18n/stamp-classes
        rm -f $(srcdir)/i18n.texi
-       builddir=`pwd`; gst=$$builddir/../gst; gst_im=$$builddir/../gst.im; \
-       cd $(srcdir) && \
-         $$gst -I $$gst_im -f ../scripts/GenLibDoc.st \
-           I18N I18N i18n.texi Load.st Collation.st
+       cd $(srcdir) && @abs_top_builddir@/gst -I @abs_top_builddir@/gst.im \
+           -f ../scripts/GenLibDoc.st I18N I18N i18n.texi Load.st Collation.st
        test -f $(srcdir)/i18n.texi && touch $(srcdir)/gst-libs.texi 
 
-$(srcdir)/regex.texi: $(top_srcdir)/examples/regex.st
-       rm -f $(srcdir)/regex.texi
-       builddir=`pwd`; gst=$$builddir/../gst; gst_im=$$builddir/../gst.im; \
-       cd $(srcdir) && \
-         $$gst -I $$gst_im -f ../scripts/GenLibDoc.st \
-           Regex Regex regex.texi
-       test -f $(srcdir)/regex.texi && touch $(srcdir)/gst-libs.texi 
-
 $(srcdir)/classes.texi: $(top_srcdir)/kernel/stamp-classes
        rm -f $(srcdir)/classes.texi
-       builddir=`pwd`; gst=$$builddir/../gst; gst_im=$$builddir/../gst.im; \
-       cd $(srcdir) && \
-         $$gst -I $$gst_im -f ../scripts/GenBaseDoc.st \
-         $(PUBLISHED_NAMESPACES)
+       cd $(srcdir) && @abs_top_builddir@/gst -I @abs_top_builddir@/gst.im \
+           -f ../scripts/GenBaseDoc.st $(PUBLISHED_NAMESPACES)
        test -f $(srcdir)/classes.texi && touch $(srcdir)/gst-base.texi
 
 # In TeX output, having colons in index entries looks pretty, but


--- orig/doc/gst.texi
+++ mod/doc/gst.texi
@@ -114,11 +114,6 @@ programming language.
 * Emacs::               @gst{} and Emacs.
 * C and Smalltalk::     @gst{}'s C/Smalltalk interoperability features.
 * Tutorial::            An introduction to Smalltalk and OOP.
-* Future::              Tasks for @gst{}'s subsequent releases.
-                        Volunteers to help out in performing some of these
-                        tasks would be greatly appreciated.
-                        Please see this node to find out what you can do
-                        to help make @gst{} a truly winning system.
 
 @detailmenu
 --- The detailed node listing ---
@@ -132,6 +127,11 @@ Using GNU Smalltalk:
 * Test suite::          How to run the test suite system.
 * Legal concerns::      Licensing of GNU Smalltalk
 
+Operation:
+* Command-line processing::        Picking an image path and a kernel path.
+* Loading or creating an image::   Loading an image or creating a new one.
+* Starting the system::            After the image is created or restored.
+
 Legal concerns:
 * GPL::                 Complying with the GNU GPL.
 * LGPL::                Complying with the GNU LGPL.
@@ -302,7 +302,7 @@ names, but their effect is as if they we
 various flags are interpreted as follows:
 
 @table @option
address@hidden -a --smalltalk
address@hidden -a --smalltalk-args
 Used to make arguments available to Smalltalk code.  The C option parser
 discards everything after the parameter including @option{-a}, while
 Smalltalk code can get it sending the @code{arguments} message to the
@@ -357,11 +357,34 @@ This option and the following one is dis
 translator (@pxref{Dynamic translator}) is enabled.
 @end ignore
 
address@hidden -E --kernel-declaration-trace
address@hidden -E --kernel-execution-trace
 Like the -e flag, but includes all byte codes executed, whether they
 occur during the loading of the kernel method definition files, or
 during the loading and execution of user files.
 
address@hidden --image-directory
address@hidden --kernel-directory
+Specify, respectively, the directory in which the image file @file{gst.im}
+will be looked for and saved, and the directory from which the kernel
+source files will be loaded.  These are used mostly while compiling
address@hidden itself.
+
address@hidden --no-user-files
+Specify that, if an image is created, @gst{} shall not load any file
+from the @file{.st} subdirectory of the user's home address@hidden
+  directory would be called @file{_st/kernel} under MS-DOS.  Under OSes that
+  don't use home directories, it would be looked for in the current 
directory.}.
+This is used mostly while compiling @gst{} itself, to avoid that the
+installed image be built from files overridden by the user.
+
address@hidden -K --kernel-file
+Specify a file to be loaded from the kernel directory.  These are
+files that are usually distributed and installed together with GNU
+Smalltalk, or that are placed under the @file{.st/kernel}
+  subdirectory of the user's home address@hidden directory is
+  called @file{_st/kernel} under MS-DOS.  Under OSes that don't use home
+  directories, it is looked for in the current directory.}.
+
 @item -f --file
 This special flag is designed to prepare Smalltalk programs that can
 be invoked from the Unix shell.  The following two command lines are
@@ -410,9 +433,10 @@ stamp out of date with respect to the Sm
 kernel definitions have been loaded, a new image file will be saved.
 
 @item -I @var{file} --image-file @var{file}
-Use the image file named @var{file} as the image file to load.
-Completely bypasses checking the file dates on the kernel files and
-standard image file.
+Use the image file named @var{file} as the image file to load.  This
+option completely bypasses the standard image file and checking the file
+dates on the kernel files.  In addition, it sets the image directory
+to the path of @var{file}.
 
 @item -l --log-changes
 Produce a log of the compiled Smalltalk code to st-changes.st, in the
@@ -452,54 +476,106 @@ executed).
 @node Operation
 @section Startup sequence
 
address@hidden: @emph{The startup sequence is pretty complicated.  If you
+are not interested in its customization, you can skip the first two
+sections below.  These two sections also don't apply when the command-line
+option @option{-I} is used.}
+
address@hidden
+* Command-line processing::        Picking an image path and a kernel path.
+* Loading or creating an image::   Loading an image or creating a new one.
+* Starting the system::            After the image is created or restored.
address@hidden menu
+
address@hidden Command-line processing
address@hidden Picking an image path and a kernel path
+
 When @gst{} is invoked, the first thing it does is choosing two paths,
-respectively the ``image path'' and the ``kernel path''.  the image path
-is set to the value of the @env{SMALLTALK_IMAGE} environment variable
-(if it is defined); if @env{SMALLTALK_IMAGE} is not defined, Smalltalk
-will try the path compiled in the binary (usually, under Unix systems,
address@hidden/usr/local/share/gnu-smalltalk} or a similar data file path) and
-then the current directory.
-
-The ``kernel path'' directory in which to look for each of the kernel
-method definition files.  There are only two possibilities in this case:
-the directory pointed to by @env{SMALLTALK_KERNEL} if it is defined,
-and a subdirectory named @file{kernel} in the current directory.
-However, kernel files are not required to be in this directory:
-Smalltalk also knows about a system default location for kernel files,
-which is compiled in the binary (usually, under Unix systems,
address@hidden/usr/local/share/gnu-smalltalk/kernel} or a similar data file
-path), and which is used for kernel files not found in the directory
-chosen as above.
-
-Then, if the @option{-i} flag is not used, Smalltalk tries to find a saved
-binary image file in the image path.  If this is found, it is checked to
-be compatible with the current version of Smalltalk and with the current
-system; Smalltalk is able to load an image created on a system with the
-same @code{sizeof(long)} but different endianness (for example, a 68k
+respectively the ``image path'' and the ``kernel path''.  The image path
+is set by considering these paths in succession:
address@hidden
address@hidden the argument to the @option{--image-directory} option if it is
+  given;
address@hidden the value of the @env{SMALLTALK_IMAGE} environment variable
+  if it is defined and readable; this step will disappear in a future
+  release;
address@hidden the path compiled in the binary (usually, under Unix systems,
+  @file{/usr/local/share/smalltalk} or a similar data file path)
+  if it exists and it is readable;
address@hidden the current directory.  The current directory is also used if
+  the image has to be rebuilt but you cannot write to a directory
+  chosen according to the previous criteria.
address@hidden itemize
+
+The ``kernel path'' is the directory in which to look for each of the kernel
+method definition files.  The possibilities in this case are:
address@hidden
address@hidden the argument to the @option{--kernel-directory} option if it is 
given;
address@hidden the value of the @env{SMALLTALK_KERNEL} environment variable
+  if it is defined and readable; this step will disappear in a future
+  release;
address@hidden the path compiled in the binary (usually, under Unix systems,
+  @file{/usr/local/share/smalltalk/kernel} or a similar data file path)
+  if it exists and it is readable;
address@hidden a subdirectory named @file{kernel} of the image path.
address@hidden itemize
+
+After these are chosen, GNU Smalltalk can try to load an image (from the
+image path), or create a new one (bootstrapping it from the files in
+the kernel path).
+
address@hidden Loading or creating an image
address@hidden Loading an image or creating a new one
+
+Unless the @option{-i} flag is used, GNU Smalltalk first tries to load the
address@hidden file in the image path.  If this is found, GNU Smalltalk
+compares the write dates of all of the kernel method definition files
+against the write date of the binary image file, to avoid loading a stale
+image.  If this check passes, the image is also checked to
+be compatible with the current version of the virtual machine and with the
+current system; GNU Smalltalk is able to load an image created on a system with
+the same pointer size but different endianness (for example, a PowerPC
 image on an x86), but not an image created on a system with different
address@hidden(long)} like an Alpha image on an x86.  Finally, if the
-images are compatible, it compares the write dates of all of the kernel
-method definition files against the write date of the binary image file.
+pointer sizes like an x86-64 image on an x86.  If the
+image is not stale and compatible, it is loaded---thus terminating the
+startup here.
 
 If the image is not found, is incompatible, or older than any of the
-kernel files, a new image has to be created.  The set of files that make
-up the kernel is loaded, one at a time.  The list can be found in
address@hidden/lib.c}, in the @code{standardFiles} variable.  If the image
-lies in the current directory, or if at least a kernel file was found
-outside of the system default path, a user-dependant
address@hidden@footnote{ The file is called @file{_stpre} under MS-DOS
-and @file{.gstpre} on the Atari ST.  Under OSes that don't use home
-directories it is looked for in the current directory.}
+kernel files, a new image has to be created.  The image path may
+now be changed to the current directory if the previous choice
+is not writeable.
+
+The set of files that make up the kernel is loaded,
+one at a time.  The list can be found in @file{libgst/lib.c}, in the
address@hidden variable.  The user can override
+kernel files by placing their own copies under the @file{.st/kernel}
+subdirectory of the user's home address@hidden directory is
+  called @file{_st/kernel} under MS-DOS.  Under OSes that don't use home
+  directories, it is looked for in the current directory.}.
+
+Before saving the image, GNU Smalltalk will load two files that
+allow easy customization, as well as installation of bug fixes.  The
+first file is @file{site-pre.st}, which should be placed in the parent
+directory of the kernel directory.  Since the kernel directory is rarely
+changed from its default, a @file{site-pre.st} file under
address@hidden/usr/local/share/smalltalk} provides a point for site-wide 
+customization.  The second file is a user-dependent @file{.st/pre.st}
+file from the user's home address@hidden file is looked up as
+  @file{_st/pre.st} under MS-DOS and again, under OSes that don't use
+  home directories it is looked for as @file{pre.st} in the current
+  directory.}.
+
address@hidden Starting the system
address@hidden After the image is created or restored
 
 At this point, independent of whether the binary image file was loaded
-or created, the @code{initialize} event is sent to the dependants of the
-special class @code{ObjectMemory} (@pxref{Memory access}).  After the
-initialization blocks have been executed, the user initialization file
address@hidden is loaded if found in the user's home
address@hidden same considerations made above hold here too.
-The file is called @file{_stinit} under MS-DOS and @file{.gstinit} on
-the Atari ST, and is looked for in the current directory under OSes that
-don't use home directories.}.
+or created, the @code{returnFromSnapshot} event is sent to the dependents of
+the special class @code{ObjectMemory} (@pxref{Memory access}).  After these
+finish executing their initialization code, the user file @file{.st/init.st} is
+loaded if found in the user's home address@hidden same considerations
+  made above hold here too.  The file is called @file{_st/init.st} under 
MS-DOS,
+  and is looked for in the current directory under OSes that don't use home
+  directories.}.
 
 Finally, if there were any files specified on the command line, they are
 loaded, otherwise standard input is read and executed until an EOF is
@@ -516,9 +592,9 @@ the command prompt: you can use @kbd{C-c
 
 The language that @gst{} accepts is based on the @dfn{file out} syntax
 as shown in the @dfn{Green Book}, also known as @cite{Smalltalk-80: Bits
-of History, Words of Advice} by Glenn Krasner.  The entire grammar of
address@hidden is described in the @file{libgst/gst.y} file, but a brief 
description
-may be in order:
+of History, Words of Advice} by Glenn Krasner.  The grammar of
address@hidden is not different from the grammar of other Smalltalk 
environments,
+but a brief description may be in order:
 @example
 <statements> !
 @end example
@@ -602,11 +678,7 @@ make check
 @end example
 
 You should see the names of the test suite files as they are processed,
-but that's it.  Any other output indicates some problem.  The only
-system that I know of which currently fails the test suite is the NeXT,
-and this is apparently due to their non-standard C runtime libraries.
-
-The test suite is by no means exhaustive.  @xref{Future}.
+but that's it.  Any other output indicates some problem.
 
 
 @node Legal concerns
@@ -768,7 +840,7 @@ that enable one to tune the virtual mach
 methods that in the past were instance methods of Smalltalk or class
 methods of Memory are now class methods of ObjectMemory.  In addition,
 and that's what the rest of this section is about, the virtual machines
-signals events to its dependants exactly through this class.
+signals events to its dependents exactly through this class.
 
 The events that can be received are
 @table @dfn
@@ -1489,11 +1561,11 @@ to define all the functions in the C run
 that this is a potential security problem (especially if your program is
 SUID root under Unix), so you might want to disable dynamic loading when
 using @gst{} as an extension language.  To disable dynamic loading,
-configure @gst{} passing the @option{--without-dld} switch.
+configure @gst{} passing the @option{--disable-dld} switch.
 
 Note that a @code{DLD} class will be present even if dynamic loading is
 disabled (either because your system is not supported, or by the
address@hidden configure switch) but any attempt to perform
address@hidden configure switch) but any attempt to perform
 dynamic linking will result in an error.
 
 @node Packages
@@ -1501,16 +1573,27 @@ dynamic linking will result in an error.
 
 Thanks to Andreas Klimas' insight, @gst{} now includes a
 powerful packaging system which allows one to file in components
-(@dfn{goodies} in Smalltalk's very folkloristic terminology)
-without caring of whether they need other goodies to be loaded.
+(often called @dfn{goodies} in Smalltalk's very folkloristic
+terminology) without caring of whether they need other goodies to be
+loaded first.
 
 The packaging system is implemented by a Smalltalk class,
 @code{PackageLoader}, which looks for information about packages in
-the XML file named (guess what) @file{packages.xml}, in the current image
-directory. There are two ways to load something using the packaging
-system. The first way is to use the PackageLoader's
address@hidden:} and @code{fileInPackages:} methods.
-For example:
+the XML file named (guess what) @file{packages.xml}, in one of three
+places:
address@hidden
address@hidden the kernel directory's parent directory; this is where
+  an installed @file{packages.xml} resides, in a system-wide data
+  directory such as @file{/usr/local/share/smalltalk};
address@hidden in the file @file{.st/packages.xml}, hosting per-user packages;
address@hidden finally, there can be a @file{packages.xml} in the same directory
+  as the current image.
address@hidden itemize
+
+There are two ways to load something using the packaging system. The
+first way is to use the PackageLoader's @code{fileInPackage:} and
address@hidden:} methods.  For example:
+
 @example
     PackageLoader fileInPackages: #('Blox' 'Browser').
     PackageLoader fileInPackage: 'Compiler'.
@@ -4162,52 +4245,6 @@ objects were registered from the same fu
 @chapter Tutorial
 @include tutorial.texi
 
address@hidden Future
address@hidden Future directions for @gst{}
-
-Presented below is the set of tasks that I feel need to be performed to
-make @gst{} a more fully functional, viable system.  They are presented
-in no particular order; other tasks are listed in the @file{TODO} file,
-in the main distribution directory.
-
-I would @emph{very much} welcome any volunteers who would like to help
-with the implementation of one or more of these tasks.  Please write at
address@hidden@@gnu.org} if you are interested in adding your
-efforts to the @gst{} project.
-
-Tasks:
address@hidden @bullet
address@hidden
-Port software to @gst{}.  The class library has proven to be quite
-robust; it should be easy to port packages (especially free ones!) to
address@hidden if the source dialect is reasonably @sc{ansi}-compliant.  One
-area which might give problems is namespaces, which is not standardized,
-and possibly exception handling for which most dialects have been
-cooking their own syntax for years.
-
address@hidden
-Port to other computers/operating systems.  The code thus far has shown
-itself to be relatively portable to various machines and Unix
-derivatives.  The architecture must support 32 or 64 bit pointers the
-same size as a long integers; in addition, the operating system had
-better be advanced enough to support asynchronous file polling and
-explicit allocation of virtual memory address ranges.
-
address@hidden
-Modify the Delay class primitive so that it does not fork a new process
-each time it is called when @code{setitimer} or a similar function call
-is not available; this involves using a pipe.  I want to do it somewhen,
-but if you do it before me, please tell me.
-
address@hidden
-Port Blox to @sc{gtk+}.
-
address@hidden
-More ideas are sketched in the @file{TODO} file, in the main distribution
-directory.
address@hidden itemize
-
-
 @iftex
 @contents
 @end iftex


--- orig/gst-package.in
+++ mod/gst-package.in
@@ -67,8 +67,11 @@ func_install ()
   set +e
 }
 
-IMAGE_PATH=${SMALLTALK_IMAGE:address@hidden@/@address@hidden
-(cd $IMAGE_PATH 2> /dev/null && IMAGE_PATH=`pwd`)
+if test -n "$SMALLTALK_IMAGE" && test -d "$SMALLTALK_IMAGE"; then
+  IMAGE_PATH=$SMALLTALK_IMAGE
+else
+  IMAGE_PATH="@datadir@/@PACKAGE@"
+fi
 
 request_help=false
 request_version=false
@@ -107,6 +110,20 @@ while [ -n "$1" ]; do
        --di | --dis | \
        --dist)          load=false; dist=:                ;;
 
+        --i | --im | --ima | --imag | --image | --image- | \
+        --image-d | --image-di | --image-dir | --image-dire | \
+       --image-direc | --image-direct | --image-directo | \
+       --image-director | --image-directory)  
+                        shift; IMAGE_PATH="$1"
+                        test -d "$1" || echo Invalid image directory ;;
+
+        --i=* | --im=* | --ima=* | --imag=* | --image=* | --image-=* | \
+        --image-d=* | --image-di=* | --image-dir=* | --image-dire=* | \
+       --image-direc=* | --image-direct=* | --image-directo=* | \
+       --image-director=* | --image-directory=*)  
+                        IMAGE_PATH="`echo $1 | sed s/.*=//`"
+                        test -d "$1" || echo Invalid image directory ;;
+
        --l=* | --li=* | --lis=* | --list=* | --list-=* | \
        --list-f=* | --list-fi=* | --list-fil=* | --list-file=* | \
        --list-files=*)  list_files="$list_files `echo $1 | sed s/.*=//`"
@@ -122,9 +139,11 @@ while [ -n "$1" ]; do
        --s=* | --sr=* | --src=* | --srcd=* | --srcdi=* | \
        --srcdir=*)      srcdir="`echo $1 | sed s/.*=//`"  ;;
 
+       --distd | --distdi | --distdir | \
        --de | --des | --dest | --destd | --destdi | \
        --destdir)       shift; DESTDIR="$1"               ;;
 
+       --distd=* | --distdi=* | --distdir=* | \
        --de=* | --des=* | --dest=* | --destd=* | --destdi=* | \
        --destdir=*)     DESTDIR="`echo $1 | sed s/.*=//`" ;;
 
@@ -138,23 +157,26 @@ while [ -n "$1" ]; do
   shift
 done
 
+(cd $IMAGE_PATH 2> /dev/null && IMAGE_PATH=`pwd`)
+
 # Do --help and --version.
 
 if [ -z "$files" ] || $request_help || $options_error; then
   cat <<EOF
 Syntax: gst-package [OPTION]... FILES...
 
-    -n, --dry-run         print commands rather than running them
-       --no-load         don't load the Smalltalk files in the image
-        --no-install      don't copy the files
-        --uninstall       remove the packages mentioned in the FILES
-        --dist            create symbolic links of non-built files
-        --list-files PKG  just output the list of files in the package
-       --srcdir DIR      look for non-built files in directory DIR
-       --destdir DIR     prefix the destination directory with DIR
+    -n, --dry-run               print commands rather than running them
+       --no-load               don't load the Smalltalk files in the image
+        --no-install            don't copy the files
+        --uninstall             remove the packages mentioned in the FILES
+        --dist                  create symbolic links of non-built files
+        --list-files PKG        just output the list of files in the package
+       --srcdir DIR            look for non-built files in directory DIR
+       --destdir DIR           prefix the destination directory with DIR
+        --image-directory DIR   set the image directory to DIR
 
-       --help            display this message and exit
-       --version         print version information and exit
+       --help                  display this message and exit
+       --version               print version information and exit
 
 Except in uninstall and list files mode, gst-package requires write
 access to the \`packages.xml' file in the GNU Smalltalk image directory,
@@ -223,7 +245,7 @@ fi
 if $dist; then
   :
 else
-  base="$DESTDIR$IMAGE_PATH/packages.xml"
+  base="$DESTDIR/packages.xml"
   if test -f $base; then
     merged_files="$base"
     for file in $files; do
@@ -238,7 +260,7 @@ else
     sed -e '$i\
 </packages>' -e '/<.packages>/,/<packages>/d' $merged_files > packages.tmp
 
-    mv packages.tmp $DESTDIR$IMAGE_PATH/packages.xml
+    mv packages.tmp $DESTDIR/packages.xml
   }
 fi
 
@@ -287,7 +309,7 @@ if $install; then
           dest=$DESTDIR$file
           orig_file=$file ;;
          *)
-          dest="$DESTDIR$IMAGE_PATH/$dir/$file"
+          dest="$DESTDIR/$dir/$file"
           file=$dir/$file
           orig_file=$file
           test -f "$file" || file=$wd/$file ;;


--- orig/kernel/Directory.st
+++ mod/kernel/Directory.st
@@ -70,14 +70,21 @@ module
 !
 
 systemKernel
-    "Answer the path to the GNU Smalltalk kernel's Smalltalk source files"
-    ^KernelFileSystemPath
+    "Answer the path to the GNU Smalltalk kernel's Smalltalk source files.
+     Same as `Directory kernel' since GNU Smalltalk 2.4."
+    ^self kernel
 !
 
 localKernel
-    "Answer the path in which a local version of the GNU Smalltalk kernel's
-     Smalltalk source files were found"
-    ^KernelFileLocalPath
+    "Answer the path to the GNU Smalltalk kernel's Smalltalk source files.
+     Same as `Directory kernel' since GNU Smalltalk 2.4."
+    ^self kernel
+!
+
+userBase
+    "Answer the base path under which file for user customization of GNU
+     Smalltalk are stored."
+    ^UserFileBasePath
 !
 
 temporary


--- orig/kernel/PkgLoader.st
+++ mod/kernel/PkgLoader.st
@@ -217,19 +217,18 @@ baseDirs: baseDirs
      directories 2 and 3 are searched.  For a packages.xml directory in
      the local image directory, instead, only directory 3 is searched."
 
-    | found |
     files := self findBaseDirs: baseDirs for: self files.
     fileIns := self findBaseDirs: baseDirs for: self fileIns.
     builtFiles := self findBaseDirs: baseDirs for: self builtFiles.
 
-    found := nil.
+    files isNil | fileIns isNil | builtFiles isNil ifTrue: [ ^false ].
+
     baseDirs
        do: [ :dir || name |
             name := Directory append: self directory to: dir.
-            (Directory exists: name) ifTrue: [ found := name ] ].
-    directory := found.
+            (Directory exists: name) ifTrue: [ directory := name. ^true ] ].
 
-    ^files notNil & fileIns notNil & builtFiles notNil & directory notNil
+    ^false
 !
 
 findBaseDirs: baseDirs for: aCollection
@@ -384,15 +383,15 @@ flush
 
 refreshDependencies
     "Reload the `packages.xml' file in the image and kernel directories.
-     The three possible places are 1) the system kernel directory's parent
-     directory, 2) the local kernel directory's parent directory, 3) the
+     The three possible places are 1) the kernel directory's parent
+     directory, 2) the `.st' subdirectory of the user's home directory, 3) the
      local image directory (in order of decreasing priority).
 
-     For a packages.xml found in the system kernel directory's parent
+     For a packages.xml found in the kernel directory's parent
      directory, all three directories are searched.  For a packages.xml
-     found in the local kernel directory's parent directory, only
-     directories 2 and 3 are searched.  For a packages.xml directory in
-     the local image directory, instead, only directory 3 is searched."
+     found in the `.st' subdirectory, only directories 2 and 3 are
+     searched.  For a packages.xml directory in the local image directory,
+     finally, only directory 3 is searched."
     | state |
     LoadDate isNil ifFalse: [
        self stillValid ifTrue: [ ^self ]
@@ -401,16 +400,14 @@ refreshDependencies
     LoadDate := Date dateAndTimeNow.
     Packages := LookupTable new.
     self
-       processPackageFile: self systemPackageFileName
-       baseDirectories: {
-           Directory systemKernel, '/..'. Directory kernel, '/..'.
-           Directory image }.
-    self
        processPackageFile: self packageFileName
-       baseDirectories: { Directory kernel, '/..'. Directory image }.
+       baseDirectories: { Directory userBase.  Directory kernel, '/..' }.
+    self
+       processPackageFile: self userPackageFileName
+       baseDirectories: { Directory userBase }.
     self
        processPackageFile: self localPackageFileName
-       baseDirectories: { Directory image }.
+       baseDirectories: #().
 ! !
 
 
@@ -507,14 +504,14 @@ isLoadable: feature
 
 !PackageLoader class methodsFor: 'private - packages file'!
 
-systemPackageFileName
-    ^Directory systemKernel, '/../packages.xml'
-!
-
 packageFileName
     ^Directory kernel, '/../packages.xml'
 !
 
+userPackageFileName
+    ^Directory userBase, '/packages.xml'
+!
+
 localPackageFileName
     ^Directory image, '/packages.xml'
 !
@@ -545,11 +542,16 @@ rebuildPackageFile
     ] ensure: [ file close ]
 !
 
-processPackageFile: fileName baseDirectories: baseDirs
+processPackageFile: fileName baseDirectories: anArray
     "Private - Process the XML source in the packages file, creating
      Package objects along the way."
 
-    | cdata file stack ch tag package |
+    | cdata file stack ch tag package baseDirs |
+    baseDirs := Smalltalk imageLocal
+       ifTrue: [ { Directory image }, anArray ]
+       ifFalse: [ anArray ].
+    baseDirs isEmpty ifTrue: [ ^self ].
+
     file := [ FileStream open: fileName mode: FileStream read ]
        on: Error
        do: [ :ex | ex return: nil ].
@@ -603,7 +605,7 @@ processPackageFile: fileName baseDirecto
 !
 
 stillValid
-    ^{ self packageFileName. self localPackageFileName. self 
systemPackageFileName } 
+    ^{ self packageFileName. self userPackageFileName. self 
localPackageFileName } 
        allSatisfy: [ :name || file |
            file := File name: name.
            file exists not or: [ file lastModifyTime < LoadDate ]


--- orig/kernel/SysDict.st
+++ mod/kernel/SysDict.st
@@ -139,6 +139,11 @@ version
 
 !SystemDictionary methodsFor: 'testing'!
 
+imageLocal
+    "Answer whether the kernel directory is a subdirectory of the image
+     directory (non-local image) or not."
+    ^(File pathFor: Directory kernel) ~= Directory image!
+
 isSmalltalk
     ^true
 ! !


--- orig/kernel/VFS.st
+++ mod/kernel/VFS.st
@@ -773,17 +773,19 @@ updateMember: anArchiveMemberHandler
 
 fileSystems
     "Answer the virtual file systems that can be processed by this subclass.
-     These are given by the names of the executable files in the vfs
+     These are given by the names of the executable files in the `vfs'
      subdirectory of the image directory, of the parent of the kernel
-     directory and of the parent of the system kernel directory."
+     directory and (if the image is not the global installed image)
+     of the `.st' directory in the home directory."
     ActivePaths := WeakValueLookupTable new. 
     FileTypes := LookupTable new. 
     [ self fileSystemsIn: Directory kernel, '/../vfs' ]
        on: Error do: [ :ex | ex return ].
-    [ self fileSystemsIn: Directory image, '/vfs' ]
-       on: Error do: [ :ex | ex return ].
-    [ self fileSystemsIn: Directory systemKernel, '/../vfs' ]
+    [ self fileSystemsIn: Directory userBase, '/vfs' ]
        on: Error do: [ :ex | ex return ].
+    Smalltalk imageLocal ifTrue: [
+        [ self fileSystemsIn: Directory image, '/vfs' ]
+           on: Error do: [ :ex | ex return ] ].
        
     ^FileTypes keys asSet!
 


--- orig/libgst/dict.c
+++ mod/libgst/dict.c
@@ -816,9 +816,6 @@ _gst_init_dictionary (void)
 
   create_classes_pass2 (class_info, sizeof (class_info) / sizeof 
(class_info[0]));
 
-  add_smalltalk ("KernelFilePath",
-                _gst_string_new (_gst_kernel_file_path));
-
   init_runtime_objects ();
   _gst_tenure_all_survivors ();
 }
@@ -1024,6 +1021,7 @@ init_smalltalk_dictionary (void)
 
   add_smalltalk ("Smalltalk", _gst_smalltalk_dictionary);
   add_smalltalk ("Version", _gst_string_new (fullVersionString));
+  add_smalltalk ("KernelFilePath", _gst_string_new (_gst_kernel_file_path));
   add_smalltalk ("CObjectType", _gst_c_object_type_ctype);
   add_smalltalk ("KernelInitialized", _gst_false_oop);
   add_smalltalk ("SymbolTable", _gst_symbol_table);
@@ -1061,10 +1059,8 @@ add_smalltalk (const char *globalName,
 void
 init_runtime_objects (void)
 {
-  add_smalltalk ("KernelFileSystemPath", _gst_string_new (KERNEL_PATH));
+  add_smalltalk ("UserFileBasePath", _gst_string_new 
(_gst_user_file_base_path));
   add_smalltalk ("ModulePath", _gst_string_new (MODULE_PATH));
-  add_smalltalk ("KernelFileLocalPath",
-                _gst_string_new (_gst_kernel_file_path));
   add_smalltalk ("ImageFilePath",
                 _gst_string_new (_gst_image_file_path));
   add_smalltalk ("ImageFileName",


--- orig/libgst/lib.c
+++ mod/libgst/lib.c
@@ -65,13 +65,15 @@
 /* #define DEBUG_GETOPT */
 
 #ifdef MSDOS
-#define INIT_FILE_NAME         "_stinit"
-#define PRE_IMAGE_FILE_NAME    "_stpre"
+#define LOCAL_BASE_DIR_NAME            "_st"
 #else
-#define INIT_FILE_NAME         ".stinit"
-#define PRE_IMAGE_FILE_NAME    ".stpre"
+#define LOCAL_BASE_DIR_NAME            ".st"
 #endif
 
+#define USER_INIT_FILE_NAME            "init.st"
+#define USER_PRE_IMAGE_FILE_NAME       "pre.st"
+#define LOCAL_KERNEL_DIR_NAME          "kernel"
+#define SITE_PRE_IMAGE_FILE_NAME       "site-pre.st"
 
 
 
@@ -127,8 +129,12 @@ static const char copyright_and_legal_st
   "\nUsing default kernel path: %s" "\nUsing default image path: %s"
   "\n";
 
+#define OPT_KERNEL_DIR 2
+#define OPT_IMAGE_DIR 3
+#define OPT_NO_USER 4
+
 static const struct option long_options[] = {
-  {"smalltalk", 0, 0, 'a'},
+  {"smalltalk-args", 0, 0, 'a'},
   {"core-dump", 0, 0, 'c'},
   {"declaration-trace-user", 0, 0, 'd'},
   {"declaration-trace-all", 0, 0, 'D'},
@@ -137,6 +143,9 @@ static const struct option long_options[
   {"execution-trace-all", 0, 0, 'E'},
 #endif
   {"file", 0, 0, 'f'},
+  {"kernel-directory", 1, 0, OPT_KERNEL_DIR},
+  {"image-directory", 1, 0, OPT_IMAGE_DIR},
+  {"no-user-files", 0, 0, OPT_NO_USER},
   {"no-gc-message", 0, 0, 'g'},
   {"help", 0, 0, 'H'},
   {"rebuild-image", 0, 0, 'i'},
@@ -152,6 +161,20 @@ static const struct option long_options[
   {"verbose", 0, 0, 'V'},
   {NULL, 0, 0, 0}
 };
+
+struct loaded_file {
+  mst_Boolean kernel_path;
+  const char *file_name;
+};
+
+enum user_dir {
+  NO_USER_DIR,
+  KERNEL_USER_DIR,
+  BASE_USER_DIR
+};
+
+static struct loaded_file *loaded_files;
+int n_loaded_files;
 
 
 /* When true, this flag suppresses the printing of execution-related
@@ -165,6 +188,13 @@ int _gst_verbosity = 2;
 const char *_gst_kernel_file_path = NULL;
 const char *_gst_image_file_path = NULL;
 
+/* The ".st" directory, in the current directory or in the user's
+   home directory.  */
+const char *_gst_user_file_base_path;
+
+/* Whether to look for user files.  */
+static mst_Boolean no_user_files;
+
 /* This is the name of the binary image to load.  If it is not NULL after the
    command line is parsed, the checking of the dates of the kernel source files
    against the image file date is overridden.  If it is NULL, it is set to
@@ -217,27 +247,19 @@ static void process_stdin ();
    kernel file is found.  */
 static mst_Boolean ok_to_load_binary (void);
 
-/* Attempts to find a viable kernel Smalltalk file (.st file).  First
-   tries the current directory to allow for overriding installed kernel
-   files.  If that isn't found, the full path name of the installed kernel
-   file is stored in fullFileName.  Note that the directory part of the
-   kernel file name in this second case can be overridden by defining the
-   SMALLTALK_KERNEL environment variable to be the directory that should
-   serve as the kernel directory instead of the installed one.
+/* Attempts to find a viable Smalltalk file for user-level customization.
+   FILENAME is a simple file name, sans directory; the file name to use 
+   for the particular file is returned, or NULL if it is not found.  */
+static char *find_user_file (const char *fileName);
 
+/* Attempts to find a viable kernel Smalltalk file (.st file).
    FILENAME is a simple file name, sans directory; the file name to use 
-   for the particular kernel file is returned in the FULLFILENAME variable
-   in this variable (which must be a string large enough for any file name).
-   If there is a file in the current directory with name FILENAME, that is
+   for the particular kernel file is returned.
+   If there is a file in the .stkernel directory with name FILENAME, that is
    returned; otherwise the kernel path is prepended to FILENAME (separated
-   by a slash, of course) and that is stored in the string pointed to by
-   FULLFILENAME.
-
-   Returns true if the kernel file is found in the local directory,
-   and false if the file was found using the default path.
- */
-static mst_Boolean find_kernel_file (const char *fileName,
-                                    char *fullFileName);
+   by a slash, of course) and that is stored in the string that is returned.  
*/
+static char *find_kernel_file (const char *fileName, const char *systemPrefix,
+                              enum user_dir userDir);
 
 /* Loads the kernel Smalltalk files.  It uses a vector of file names,
    and loads each file individually.  To provide for greater
@@ -258,25 +280,17 @@ static void init_paths (void);
 static int parse_args (int argc,
                       const char **argv);
 
-/* These functions load the per-user customization files, respectively
-   .stinit (loaded at every startup) and .stpre (loaded before a local
+/* Path names for the per-user customization files, respectively
+   init.st (loaded at every startup) and pre.st (loaded before a local
    image is saved.  */
-static void load_user_init_file (void);
-static void load_user_pre_image_file (void);
+static const char *user_init_file;
+static const char *user_pre_image_file;
+static const char *site_pre_image_file;
 
 /* Set by command line flag.  When true, Smalltalk saves a snapshot after
    loading the files on the command line, before exiting.  */
 static mst_Boolean snapshot_after_load = false;
 
-/* Whether SMALLTALK_IMAGE is set (only if it is set, .stpre is loaded) */
-static mst_Boolean is_local_image;
-
-/* Usually the same as _gst_image_file_path.  */
-static char *default_image_path;
-
-/* The default_image_path followed by /gst.im */
-static char *default_image_name;
-
 /* If true, skip date checking of kernel files vs. binary image; pretend
    that binary image does not exist.  */
 static mst_Boolean ignore_image = false;
@@ -443,20 +457,19 @@ gst_init_smalltalk (void)
   mst_Boolean loadBinary, abortOnFailure;
   mst_Boolean traceUserDeclarations, traceUserExecution;
   int result;
-  char *p;
 
   /* Even though we're nowhere near through initialization, we set this
      to make sure we don't invoke a callin function which would recursively
      invoke us.  */
   _gst_smalltalk_initialized = true;
 
-  init_paths ();
   _gst_init_snprintfv ();
 
   result = parse_args (smalltalk_argc, smalltalk_argv);
   if (result)
     return result;
 
+  init_paths ();
   _gst_init_sysdep ();
   _gst_init_signals ();
   _gst_init_cfuncs ();
@@ -479,38 +492,28 @@ gst_init_smalltalk (void)
     loadBinary = abortOnFailure = true;
   else
     {
-      _gst_binary_image_name = default_image_name;
+      char *default_image_file_name;
+      asprintf (&default_image_file_name, "%s/gst.im", _gst_image_file_path);
+
+      _gst_binary_image_name = default_image_file_name;
       loadBinary = !ignore_image && ok_to_load_binary();
       abortOnFailure = false;
 
       /* If we must create a new non-local image, but the directory is
          not writeable, we must resort to the current directory.  In
-         practice this is what is used when working in the build directory.  */
+         practice this is what happens when a "normal user" puts stuff in
+        his ".st" directory or does "gst -i".  */
 
       if (!loadBinary
-          && !is_local_image
           && !_gst_file_is_writeable (_gst_image_file_path))
         {
-          is_local_image = true;
-          xfree (default_image_path);
-          _gst_image_file_path = default_image_path = _gst_get_cur_dir_name ();
+          _gst_image_file_path = _gst_get_cur_dir_name ();
           _gst_binary_image_name = "gst.im";
           loadBinary = !ignore_image && ok_to_load_binary();
+         xfree (default_image_file_name);
         }
     }
 
-  /* Compute the actual path of the image file */
-  _gst_image_file_path = p =
-    _gst_get_full_file_name (_gst_binary_image_name);
-  
-  p += strlen (_gst_image_file_path);
-#if defined(MSDOS) || defined(WIN32) || defined(__OS2__)
-  while (*--p != '/' && *p != '\\');
-#else
-  while (*--p != '/');
-#endif
-  *p = 0;
-
   if (loadBinary && _gst_load_from_file (_gst_binary_image_name))
     {
       _gst_init_interpreter ();
@@ -538,12 +541,6 @@ gst_init_smalltalk (void)
       _gst_install_initial_methods ();
 
       result = load_standard_files ();
-      if (!result)
-       {
-          if (is_local_image)
-           load_user_pre_image_file ();
-       }
-
       _gst_regression_testing = willRegressTest;
       if (result)
        return result;
@@ -554,7 +551,8 @@ gst_init_smalltalk (void)
 
   _gst_kernel_initialized = true;
   _gst_invoke_hook ("returnFromSnapshot");
-  load_user_init_file ();
+  if (user_init_file)
+    process_file (user_init_file);
 
   _gst_declare_tracing = traceUserDeclarations;
   _gst_execution_tracing = traceUserExecution;
@@ -569,27 +567,39 @@ gst_init_smalltalk (void)
 void
 gst_top_level_loop (void)
 {
-  int filesProcessed;
-
-  for (filesProcessed = 0; *++smalltalk_argv;)
+  struct loaded_file *file;
+  for (file = loaded_files; file < &loaded_files[n_loaded_files]; file++)
     {
-      if (smalltalk_argv[0][0] == '-')
-        /* - by itself indicates standard input */
+      char *f;
+      if (file->kernel_path)
+       {
+         f = find_kernel_file (file->file_name, "../", BASE_USER_DIR);
+         if (!f)
+           {
+             _gst_errorf ("Couldn't open kernel file %s", file->file_name);
+             continue;
+           }
+       }
+      else
+       f = xstrdup (file->file_name);
+
+      /* - by itself indicates standard input */
+      if (!strcmp (f, "-"))
         process_stdin ();
       else
        {
-         _gst_use_undeclared++;
-         if (!process_file (smalltalk_argv[0]))
-           _gst_errorf ("Couldn't open file %s", smalltalk_argv[0]);
-
-         _gst_use_undeclared--;
+         if (!process_file (f))
+           _gst_errorf ("Couldn't open file %s", f);
        }
-      filesProcessed++;
+
+      xfree (f);
     }
 
-  if (filesProcessed == 0)
+  if (n_loaded_files == 0)
     process_stdin ();
 
+  xfree (loaded_files);
+  n_loaded_files = 0;
   if (snapshot_after_load)
     _gst_save_to_file (_gst_binary_image_name);
 
@@ -602,43 +612,92 @@ void
 init_paths (void)
 {
   char *currentDirectory = _gst_get_cur_dir_name ();
-  const char *kernel_path, *image_path;
 
-  kernel_path = (char *) getenv ("SMALLTALK_KERNEL");
-  image_path = (char *) getenv ("SMALLTALK_IMAGE");
-  is_local_image = true;
+  const char *home = getenv ("HOME");
+
+  /* By default, apply this kludge fpr OSes such as Windows and MS-DOS
+     which have no concept of home directories.  */
+  if (home == NULL)
+    home = xstrdup (currentDirectory);
 
-  if (!kernel_path
-      || !_gst_file_is_readable (kernel_path))
+  asprintf ((char **) &_gst_user_file_base_path, "%s/%s", home, 
LOCAL_BASE_DIR_NAME);
+
+  if (_gst_binary_image_name)
     {
-      char *kernel_file_path;
-      asprintf (&kernel_file_path, "%s/kernel",
-               currentDirectory);
+      /* Compute the actual path of the image file */
+      const char *p = _gst_binary_image_name + strlen (_gst_binary_image_name);
+      for (;;)
+       if (*--p == '/'
+#if defined(MSDOS) || defined(WIN32) || defined(__OS2__)
+           || *p == '\\'
+#endif
+          )
+         {
+           char *dirname;
+           int n = p > _gst_binary_image_name ? p - _gst_binary_image_name : 1;
+           dirname = xmalloc (n + 1);
+           strncpy (dirname, _gst_binary_image_name, n);
+           _gst_image_file_path = dirname;
+           break;
+         }
 
-      _gst_kernel_file_path = kernel_file_path;
+       else if (p == _gst_binary_image_name)
+         {
+           _gst_image_file_path = ".";
+           break;
+         }
     }
-  else
-    _gst_kernel_file_path = xstrdup (kernel_path);
 
-  if (!image_path
-      || !_gst_file_is_readable (image_path))
+  /* These might go away in the next release.  */
+  if (!_gst_kernel_file_path)
     {
-      image_path = IMAGE_PATH;
+      _gst_kernel_file_path = getenv ("SMALLTALK_KERNEL");
+      if (_gst_kernel_file_path)
+       _gst_warningf ("SMALLTALK_KERNEL variable deprecated, "
+                      "use --kernel-directory instead");
+      if (!_gst_file_is_readable (_gst_kernel_file_path))
+       _gst_kernel_file_path = NULL;
+    }
+
+  if (!_gst_image_file_path)
+    {
+      _gst_image_file_path = getenv ("SMALLTALK_IMAGE");
+      if (_gst_image_file_path)
+       _gst_warningf ("SMALLTALK_IMAGE variable deprecated, "
+                      "use --image-directory instead");
+      if (!_gst_file_is_readable (_gst_image_file_path))
+       _gst_image_file_path = NULL;
+    }
+
+  if (_gst_image_file_path)
+    _gst_image_file_path = _gst_get_full_file_name (_gst_image_file_path);
+  else if (_gst_file_is_readable (IMAGE_PATH))
+    _gst_image_file_path = IMAGE_PATH;
+  else
+    _gst_image_file_path = xstrdup (currentDirectory);
 
-      if (_gst_file_is_readable (image_path))
-       /* Found in the standard image path.  Apply this kludge so
-          that OSes such as Windows and MS-DOS which have no concept 
-          of home directories always load the .stpre file.  */
-       is_local_image = (((char *) getenv ("HOME")) == NULL);
-      else
-       image_path = currentDirectory;
+  if (_gst_kernel_file_path)
+    _gst_kernel_file_path = _gst_get_full_file_name (_gst_kernel_file_path);
+  else if (_gst_file_is_readable (KERNEL_PATH))
+    _gst_kernel_file_path = KERNEL_PATH;
+  else
+    {
+      char *default_kernel_file_path;
+      asprintf (&default_kernel_file_path, "%s/kernel", _gst_image_file_path);
+      _gst_kernel_file_path = default_kernel_file_path;
     }
 
-  asprintf (&default_image_name, "%s/gst.im",
-           image_path);
-
-  _gst_image_file_path = default_image_path = xstrdup (image_path);
   xfree (currentDirectory);
+
+  site_pre_image_file = find_kernel_file (SITE_PRE_IMAGE_FILE_NAME, "../",
+                                         NO_USER_DIR);
+
+  user_pre_image_file = find_user_file (USER_PRE_IMAGE_FILE_NAME);
+
+  if (!_gst_regression_testing)
+    user_init_file = find_user_file (USER_INIT_FILE_NAME);
+  else
+    user_init_file = NULL;
 }
 
 mst_Boolean
@@ -646,7 +705,6 @@ ok_to_load_binary (void)
 {
   time_t imageFileTime;
   const char *fileName;
-  char fullFileName[MAXPATHLEN], *home, preImageFileName[MAXPATHLEN];
 
   imageFileTime = _gst_get_file_modify_time (_gst_binary_image_name);
 
@@ -655,28 +713,20 @@ ok_to_load_binary (void)
 
   for (fileName = standard_files; *fileName; fileName += strlen (fileName) + 1)
     {
-      if (find_kernel_file (fileName, fullFileName)
-         && !is_local_image)
-       {
-         /* file lives locally but the image doesn't -- bad semantics.
-            Note that if SOME of the files are local and the image file
-            is local, it is good.  */
-         return (false);
-       }
-      if (imageFileTime < _gst_get_file_modify_time (fullFileName))
-       return (false);
+      char *fullFileName = find_kernel_file (fileName, "", KERNEL_USER_DIR);
+      mst_Boolean ok = (imageFileTime > _gst_get_file_modify_time 
(fullFileName));
+      xfree (fullFileName);
+      if (!ok)
+        return (false);
     }
 
-  if (is_local_image)
-    {
-      if ((home = (char *) getenv ("HOME")) != NULL)
-       sprintf (preImageFileName, "%s/%s", home, PRE_IMAGE_FILE_NAME);
-      else
-       strcpy (preImageFileName, PRE_IMAGE_FILE_NAME);
+  if (site_pre_image_file
+      && imageFileTime <= _gst_get_file_modify_time (site_pre_image_file))
+    return (false);
 
-      if (imageFileTime < _gst_get_file_modify_time (preImageFileName))
-       return (false);
-    }
+  if (user_pre_image_file
+      && imageFileTime <= _gst_get_file_modify_time (user_pre_image_file))
+    return (false);
 
   return (true);
 }
@@ -685,81 +735,89 @@ int
 load_standard_files (void)
 {
   const char *fileName;
-  char fullFileName[MAXPATHLEN];
 
-  _gst_use_undeclared++;
   for (fileName = standard_files; *fileName; fileName += strlen (fileName) + 1)
     {
-      find_kernel_file (fileName, fullFileName);
-      if (!process_file (fullFileName))
+      char *fullFileName = find_kernel_file (fileName, "", KERNEL_USER_DIR);
+      if (!fullFileName)
        {
          _gst_errorf ("can't find system file '%s'", fullFileName);
-         _gst_errorf
-           ("image bootstrap failed, set SMALLTALK_KERNEL to the directory 
name");
+         _gst_errorf ("image bootstrap failed, use option --kernel-directory");
          return 1;
        }
+      else
+       {
+         mst_Boolean ok = process_file (fullFileName);
+         xfree (fullFileName);
+         if (!ok)
+           return 1;
+       }
     }
-  _gst_use_undeclared--;
+
+  if (site_pre_image_file)
+    process_file (site_pre_image_file);
+
+  if (user_pre_image_file)
+    process_file (user_pre_image_file);
+
   return 0;
 }
 
 
-mst_Boolean
-find_kernel_file (const char *fileName,
-                 char *fullFileName)
-{
-  if (_gst_file_is_readable (fileName))
-    {
-      strcpy (fullFileName, fileName);
-      return (true);
+char *
+find_kernel_file (const char *fileName, const char *systemPrefix,
+                 enum user_dir userDir)
+{
+  char *fullFileName, *localFileName;
+
+  asprintf (&fullFileName, "%s/%s%s", _gst_kernel_file_path, systemPrefix,
+           fileName);
+
+  if (!no_user_files && userDir != NO_USER_DIR)
+    {
+      asprintf (&localFileName, "%s/%s%s",
+               _gst_user_file_base_path,
+               userDir == BASE_USER_DIR ? "" : LOCAL_KERNEL_DIR_NAME "/",
+               fileName);
+
+      if (_gst_file_is_readable (localFileName)
+          /* If the system file is newer, use the system file instead.  */
+          && (!_gst_file_is_readable (fullFileName) ||
+             _gst_get_file_modify_time (localFileName) >=
+             _gst_get_file_modify_time (fullFileName)))
+       {
+         xfree (fullFileName);
+         return localFileName;
+       }
+      else
+       xfree (localFileName);
     }
 
-  sprintf (fullFileName, "%s/%s", _gst_kernel_file_path,
-          fileName);
   if (_gst_file_is_readable (fullFileName))
-    {
-      char systemFileName[256];
-      sprintf (systemFileName, KERNEL_PATH "/%s", fileName);
-      /* If this file and the system file are the same, consider the
-         file as a system file instead.  */
-      return (!_gst_file_is_readable (systemFileName) ||
-             _gst_get_file_modify_time (fullFileName) !=
-             _gst_get_file_modify_time (systemFileName));
-    }
+    return fullFileName;
 
-  sprintf (fullFileName, KERNEL_PATH "/%s", fileName);
-  return (false);
+  xfree (fullFileName);
+  return NULL;
 }
 
 
-void
-load_user_pre_image_file (void)
+char *
+find_user_file (const char *fileName)
 {
-  char fileName[MAXPATHLEN], *home;
+  char *fullFileName;
+  if (no_user_files)
+    return NULL;
 
-  if ((home = (char *) getenv ("HOME")) != NULL)
-    sprintf (fileName, "%s/%s", home, PRE_IMAGE_FILE_NAME);
+  asprintf (&fullFileName, "%s/%s", _gst_user_file_base_path, fileName);
+  if (!_gst_file_is_readable (fullFileName))
+    {
+      xfree (fullFileName);
+      return NULL;
+    }
   else
-    strcpy (fileName, PRE_IMAGE_FILE_NAME);
-
-  process_file (fileName);
+    return fullFileName;
 }
 
-void
-load_user_init_file (void)
-{
-  char fileName[MAXPATHLEN], *home;
-
-  if (_gst_regression_testing)
-    return;
-
-  if ((home = (char *) getenv ("HOME")) != NULL)
-    sprintf (fileName, "%s/%s", home, INIT_FILE_NAME);
-  else
-    strcpy (fileName, INIT_FILE_NAME);
-
-  process_file (fileName);
-}
 
 void
 process_stdin ()
@@ -789,9 +847,11 @@ process_file (const char *fileName)
   if (_gst_verbosity > 2)
     printf ("Processing %s\n", fileName);
 
+  _gst_use_undeclared++;
   _gst_push_unix_file (fd, fileName);
   _gst_parse_stream (false);
   _gst_pop_stream (true);
+  _gst_use_undeclared--;
   return (true);
 }
 
@@ -800,7 +860,6 @@ int
 parse_args (int argc,
            const char **argv)
 {
-  const char **av = argv;
   int ch, prev_optind = 1, minus_a_optind = -1;
 
 #ifndef ENABLE_DYNAMIC_TRANSLATION
@@ -809,6 +868,9 @@ parse_args (int argc,
 # define OPTIONS "-acdDf:ghiI:K:lL:pQqrSvV"
 #endif
 
+  loaded_files =
+    (struct loaded_file *) xmalloc (sizeof (struct loaded_file) * argc);
+
   /* get rid of getopt's own error reporting for invalid options */
   opterr = 1;
 
@@ -867,7 +929,8 @@ parse_args (int argc,
        case 'f':
          /* Same as -Q, passing a file, and -a.  */
          _gst_verbosity = 0;
-         *++av = optarg;
+         loaded_files[n_loaded_files].kernel_path = false;
+         loaded_files[n_loaded_files++].file_name = optarg;
 
        case 'a':
          /* "Officially", the C command line ends here.  The Smalltalk 
@@ -889,12 +952,31 @@ parse_args (int argc,
          break;
 
        case 'K':
-         {
-           char *file;
-           asprintf (&file, "%s/%s", _gst_image_file_path, optarg);
-           *++av = file;
-           break;
-         }
+         loaded_files[n_loaded_files].kernel_path = true;
+         loaded_files[n_loaded_files++].file_name = optarg;
+         break;
+
+       case OPT_KERNEL_DIR:
+         _gst_kernel_file_path = optarg;
+          if (!_gst_file_is_readable (_gst_kernel_file_path))
+           {
+             _gst_errorf ("kernel path %s not readable", 
_gst_kernel_file_path);
+             return 1;
+           }
+         break;
+
+       case OPT_IMAGE_DIR:
+         _gst_image_file_path = optarg;
+          if (!_gst_file_is_readable (_gst_image_file_path))
+           {
+             _gst_errorf ("image path %s not readable", _gst_image_file_path);
+             return 1;
+           }
+         break;
+
+       case OPT_NO_USER:
+         no_user_files = true;
+         break;
 
        case 'v':
          printf (copyright_and_legal_stuff_text, VERSION, KERNEL_PATH,
@@ -902,7 +984,8 @@ parse_args (int argc,
          return -1;
 
        case '\1':
-         *++av = optarg;
+         loaded_files[n_loaded_files].kernel_path = false;
+         loaded_files[n_loaded_files++].file_name = optarg;
          break;
 
        default:
@@ -927,7 +1010,8 @@ parse_args (int argc,
             is nothing after -a, or if we finished processing the argument
             which included -a, leave.  */
          _gst_smalltalk_passed_argc = argc - optind;
-         _gst_smalltalk_passed_argv = xmalloc (sizeof (char *) * 
_gst_smalltalk_passed_argc);
+         _gst_smalltalk_passed_argv =
+           xmalloc (sizeof (char *) * _gst_smalltalk_passed_argc);
          memcpy (_gst_smalltalk_passed_argv, argv + optind,
                  sizeof (char *) * _gst_smalltalk_passed_argc);
          break;
@@ -936,6 +1020,5 @@ parse_args (int argc,
       prev_optind = optind;
     }
 
-  *++av = NULL;
   return 0;
 }


--- orig/libgst/lib.h
+++ mod/libgst/lib.h
@@ -62,6 +62,10 @@ extern const char *_gst_kernel_file_path
 extern const char *_gst_image_file_path 
   ATTRIBUTE_HIDDEN;
 
+/* The ".st" directory, in the current directory or in the user's
+   home directory.  */
+extern const char *_gst_user_file_base_path;
+
 /* This is the name of the binary image to load.  If it is not NULL after the
    command line is parsed, the checking of the dates of the kernel source files
    against the image file date is overridden.  If it is NULL, it is set to


--- orig/libgst/sysdep.c
+++ mod/libgst/sysdep.c
@@ -737,36 +736,154 @@ _gst_get_cur_dir_name (void)
 }
 
 
 char *
-_gst_get_full_file_name (const char *fileName)
+_gst_get_full_file_name (const char *name)
 {
-  char *fullFileName;
-  static char *fullPath = NULL;
+  char *rpath, *dest;
+  const char *start, *end, *rpath_limit;
+  long int path_max;
+#ifdef HAVE_READLINK
+  int num_links = 0;
+  char *extra_buf = NULL;
+#endif
+
+#ifdef PATH_MAX
+  path_max = PATH_MAX;
+#else
+  path_max = pathconf (name, _PC_PATH_MAX);
+  if (path_max <= 0)
+    path_max = 1024;
+#endif
 
-  if (fileName[0] == '/')      /* absolute, so don't need to change */
-    return (xstrdup (fileName));
+  rpath = malloc (path_max);
+  if (rpath == NULL)
+    return NULL;
+  rpath_limit = rpath + path_max;
 
-  if (fullPath == NULL)
+  if (name[0] != '/')
     {
-      /* Only need to do this once, then cache the result */
-      fullPath = _gst_get_cur_dir_name ();
+      if (!getcwd (rpath, path_max))
+       {
+         rpath[0] = '\0';
+         goto error;
+       }
+      dest = strchr (rpath, '\0');
+    }
+  else
+    {
+      rpath[0] = '/';
+      dest = rpath + 1;
     }
 
-  /* 
-   * ### canonicalize filename and full path here in the future (remove any
-   * extraneous .. or . directories, etc.)
-   */
+  for (start = end = name; *start; start = end)
+    {
+      struct stat st;
+
+      /* Skip sequence of multiple path-separators.  */
+      while (*start == '/')
+       ++start;
+
+      /* Find end of path component.  */
+      for (end = start; *end && *end != '/'; ++end)
+       /* Nothing.  */;
+
+      if (end - start == 0)
+       break;
+      else if (end - start == 1 && start[0] == '.')
+       /* nothing */;
+      else if (end - start == 2 && start[0] == '.' && start[1] == '.')
+       {
+         /* Back up to previous component, ignore if at root already.  */
+         if (dest > rpath + 1)
+           while ((--dest)[-1] != '/');
+       }
+      else
+       {
+         size_t new_size;
+
+         if (dest[-1] != '/')
+           *dest++ = '/';
+
+         if (dest + (end - start) >= rpath_limit)
+           {
+             ptrdiff_t dest_offset = dest - rpath;
+             char *new_rpath;
+
+             new_size = rpath_limit - rpath;
+             if (end - start + 1 > path_max)
+               new_size += end - start + 1;
+             else
+               new_size += path_max;
+             new_rpath = (char *) realloc (rpath, new_size);
+             if (new_rpath == NULL)
+               goto error;
+             rpath = new_rpath;
+             rpath_limit = rpath + new_size;
 
-  fullFileName = (char *) xmalloc (strlen (fullPath) + strlen (fileName) + 1   
/* slash 
-                                                                               
 */
-                                  + 1 /* trailing nul */ );
-  sprintf (fullFileName, "%s/%s", fullPath, fileName);
-  return (fullFileName);
+             dest = rpath + dest_offset;
+           }
+
+         memcpy (dest, start, end - start);
+         dest += end - start;
+         *dest = '\0';
+
+         if (lstat (rpath, &st) < 0)
+           goto error;
+
+#if HAVE_READLINK
+         if (S_ISLNK (st.st_mode))
+           {
+             char *buf;
+             size_t len;
+             int n;
+
+             if (++num_links > MAXSYMLINKS)
+               {
+                 errno = ELOOP;
+                 goto error;
+               }
+
+             buf = alloca (path_max);
+             n = readlink (rpath, buf, path_max);
+             if (n < 0)
+               {
+                 int saved_errno = errno;
+                 errno = saved_errno;
+                 goto error;
+               }
+             buf[n] = '\0';
+             if (!extra_buf)
+               extra_buf = alloca (path_max);
+
+             len = strlen (end);
+             if ((long int) (n + len) >= path_max)
+               {
+                 errno = ENAMETOOLONG;
+                 goto error;
+               }
+
+             /* Careful here, end may be a pointer into extra_buf... */
+             memmove (&extra_buf[n], end, len + 1);
+             name = end = memcpy (extra_buf, buf, n);
+
+             if (buf[0] == '/')
+               dest = rpath + 1;       /* It's an absolute symlink */
+             else
+               /* Back up to previous component, ignore if at root already: */
+               if (dest > rpath + 1)
+                 while ((--dest)[-1] != '/');
+           }
+#endif
+       }
+    }
+  if (dest > rpath + 1 && dest[-1] == '/')
+    --dest;
+  *dest = '\0';
+  return rpath;
+
+error:
+  {
+    int saved_errno = errno;
+    free (rpath);
+    errno = saved_errno;
+  }
+  return NULL;
 }
 
 


--- orig/scripts/Finish.st
+++ mod/scripts/Finish.st
@@ -28,7 +28,7 @@
 |
  ======================================================================"
 
-"Invoked as Finish.st DESTDIR/PKGDATADIR PKGDATADIR [MODULES]..."
+"Invoked as Finish.st PKGDATADIR [MODULES]..."
 
 | ok |
 ok := false.
@@ -41,14 +41,15 @@ ok ifFalse: [ ObjectMemory quit: 1 ]!
 
 "Symbol rebuildTable."
 
-"Remove DESTDIR from the paths stored in the image"
-| old new |
-old := Smalltalk arguments first.
-new := Smalltalk arguments at: 2.
-old = new ifFalse: [ FileSegment relocateFrom: old to: new ].
+"Remove DESTDIR and references to the build directory, from the paths
+ stored in the image"
+| new |
+new := Smalltalk arguments first.
+ImageFilePath = new ifFalse: [ FileSegment relocateFrom: ImageFilePath to: new 
].
 ImageFileName := 'gst.im'.
+ImageLocal := false.
 ImageFilePath := new.
-KernelFileLocalPath := new, '/kernel'. 
-KernelFilePath := new, '/kernel'!
+KernelFilePath := new, '/kernel'.
+UserFileBasePath := nil!
 
 ObjectMemory snapshot!


--- orig/tests/Makefile.am
+++ mod/tests/Makefile.am
@@ -109,17 +109,15 @@ EXTRA_DIST = run-test
 $(ansi_tests):
 
 regress:
-       SMALLTALK_KERNEL="$(top_srcdir)/kernel/"; \
-       export SMALLTALK_KERNEL; \
+       cd $(srcdir) || exit 1; \
        for test in $(low_level_tests) $(benchmark_tests); do \
          result=`echo $$test | $(SED) 's/st$$/ok/'`; \
-         $(top_builddir)/gst -I $(top_builddir)/gst.im \
-               -r $$test 2>&1 | tee $$result; \
+         @abs_top_builddir@/gst -I @abs_top_builddir@/gst.im \
+           -r $$test 2>&1 | tee $$result; \
        done
 
 gst.im: ../kernel/stamp-classes AnsiLoad.st Ansi.st AnsiDB.st
-       cp ../gst.im .
-       builddir=`pwd` && \
+       cp $(top_builddir)/gst.im .
        cd $(srcdir) && \
-       $$builddir/../gst -QSI $$builddir/gst.im AnsiLoad.st
+         @abs_top_builddir@/gst -SI @abs_top_builddir@/tests/gst.im AnsiLoad.st
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]