changeset 666:fb4f6556b443

[project @ 1994-09-06 21:22:46 by jwe]
author jwe
date Tue, 06 Sep 1994 21:25:14 +0000
parents 2aeae851a164
children b19a14bbd862
files Makeconf.in configure.in octMakefile.in src/Makefile.in src/defaults.h.in src/octave.cc src/parse.y src/pt-exp-base.cc src/pt-exp-base.h src/schur.cc src/variables.cc
diffstat 11 files changed, 467 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/Makeconf.in
+++ b/Makeconf.in
@@ -81,47 +81,87 @@
 # and gets us back up to the top level of the source tree.
 version = `$(getversion) $(srcdir)/$(TOPDIR)/src/version.h`
 
-# Common prefix for installation directories.
-# NOTE: This directory must exist when you start installation.
-prefix = /usr/local
+# ==================== Where To Install Things ====================
 
-# Directory in which to put host dependent programs and libraries
-exec_prefix = $(prefix)
+# The default location for installation.  Everything is placed in
+# subdirectories of this directory.  The default values for many of
+# the variables below are expressed in terms of this one, so you may
+# not need to change them.  This defaults to /usr/local.
+prefix = @prefix@
 
-# Where to install the executables.
-bindir = $(exec_prefix)/bin
+# Like `prefix', but used for architecture-specific files.
+exec_prefix = @exec_prefix@
+
+# Where to install Octave and other binaries that people will want to
+# run directly.
+bindir = @bindir@
 
-# Where to put libraries like libcruft.a, liboctave.a, and libreadline.a
-libdir = $(exec_prefix)/lib
+# Where to install architecture-independent data files.  ${fcnfiledir}
+# and ${localfcnfiledir} are subdirectories of this.
+datadir = @datadir@
 
-# Where octave will look for M-files
-libsubdir = $(libdir)/octave/$(version)
+# Where to install and expect libraries like libcruft.a, liboctave.a,
+# and libreadline.a, executable files to be run by Octave rather than
+# directly by users, and other architecture-dependent data.
+# ${archlibdir} is a subdirectory of this. 
+libdir = @libdir@
 
-# Where to put the manual pages.
-mandir = $(prefix)/man/man1
-# Extension (not including `.') for the installed manual page filenames.
+# Where to install Octave's include files.  The default is
+# ${prefix}/include/octave
+includedir = @includedir@
+
+# Where to install Octave's man pages, and what extension they should
+# have.  The default is ${prefix}/man/man1
+mandir = @mandir@
 manext = 1
 
-# Where to put the info files.
-infodir = $(prefix)/info
+# Where to install and expect the info files describing Octave..
+infodir = @infodir@
+
+# ==================== Octave-specific directories ====================
+
+# These variables hold the values Octave will actually use.  They are
+# based on the values of the standard Make variables above.
+
+# Where to install the function file distributed with
+# Octave.  This includes the Octave version, so that the
+# function files for different versions of Octave will install
+# themselves in separate directories.
+fcnfiledir = @fcnfiledir@
+
+# Directories Octave should search for function files specific
+# to this site (i.e. customizations), before consulting
+# ${fcnfiledir}.  This should be a colon-separated list of
+# directories.
+localfcnfilepath = @localfcnfilepath@
 
-# Where to put extra data files, system-wide startup files, etc.
-datadir = $(prefix)/lib/octave
+# Where to put executables to be run by Octave rather than
+# the user.  This path usually includes the Octave version
+# and configuration name, so that multiple configurations
+# for multiple versions of Octave may be installed at once.
+archlibdir = @archlibdir@
+
+# Where to put object files that will by dynamically loaded.
+# This path usually includes the Octave version and configuration
+# name, so that multiple configurations for multiple versions of
+# Octave may be installed at once. 
+octfiledir = @octfiledir@
 
-# Where to put installed include files.
-includedir = $(prefix)/include/octave
+# Directories Octave should search for object files that will be
+# dynamically loaded and that are specific to this site
+# (i.e. customizations), before consulting ${octfiledir}.  This should
+# be a colon-separated list of directories.
+localoctfilepath = @localoctfilepath@
+
+# Where Octave will search to find its function files.  Before
+# changing this, check to see if your purpose wouldn't
+# better be served by changing localfcnfilepath.  This
+# should be a colon-separated list of directories.
+fcnfilepath = @fcnfilepath@
 
 # The type of computer we are running on.
 target_host_type = @target_host_type@
 
-# Normally this is the same as $(prefix).  With --run-in-place it is
-# $(srcdir).
-OCTAVE_HOME = @OCTAVE_HOME@
-
-# These are not used unless RUN_IN_PLACE is defined.
-OCTAVE_INFO_DIR = @OCTAVE_INFO_DIR@
-OCTAVE_LIB_DIR = @OCTAVE_LIB_DIR@
-
 # The following pattern rules and the substitution functions require
 # GNU make.  If you don't have it, get it!
 
--- a/configure.in
+++ b/configure.in
@@ -21,7 +21,7 @@
 dnl along with Octave; see the file COPYING.  If not, write to the Free
 dnl Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 dnl
-AC_REVISION($Revision: 1.39 $)dnl
+AC_REVISION($Revision: 1.40 $)dnl
 AC_PREREQ(1.8)dnl
 AC_INIT(src/octave.cc)
 AC_CONFIG_HEADER(config.h)
@@ -73,16 +73,34 @@
 dnl
 AC_ENABLE(dld, use_dld=true, use_dld=false)dnl
 dnl
-dnl Makes Octave look for info and function files in the same
-dnl directory tree as the sources
+dnl some defaults
 dnl
-AC_ENABLE(run-in-place, run_in_place=true, run_in_place=false)dnl
-OCTAVE_HOME=/usr/local
-if test -n "$prefix"; then
-  OCTAVE_HOME=$prefix
-fi
-OCTAVE_LIB_DIR=
-OCTAVE_INFO_DIR=
+exec_prefix='$(prefix)'
+bindir='$(exec_prefix)/bin'
+datadir='$(prefix)/lib'
+libdir='$(exec_prefix)/lib'
+includedir='$(prefix)/include'
+mandir='$(prefix)/man/man1'
+infodir='$(prefix)/info'
+fcnfiledir='$(datadir)/octave/$(version)/m'
+localfcnfilepath='$(datadir)/octave/site-m'
+archlibdir='$(libdir)/octave/$(version)/$(target_host_type)/exec'
+octfiledir='$(archlibdir)/oct'
+localoctfilepath='$(datadir)/octave/$(target_host_type)/site-oct'
+fcnfilepath='.:$(localoctfilepath):$(localfcnfilepath):$(octfiledir):$(fcnfiledir)'
+dnl
+dnl Handle --enable-run-in-place.  This option makes Octave look for
+dnl info and function files in the same directory tree as the sources.
+dnl
+AC_ENABLE(run-in-place, [
+  run_in_place=true;
+  if test "$enableval" = "yes"; then
+    builddir="."
+  else
+    builddir=enableval
+  fi
+], run_in_place=false)dnl
+dnl
 if $run_in_place; then
   AC_DEFINE(RUN_IN_PLACE, 1)dnl
   case "$srcdir" in
@@ -90,20 +108,53 @@
       absolute_srcdir=$srcdir
     ;;
     *)
-      AC_WARN([making OCTAVE_HOME absolute -- may lose with automounter])
+      AC_WARN([making srcdir absolute -- may lose with automounter])
       absolute_srcdir=`(cd $srcdir; pwd)`
     ;;
   esac
-  OCTAVE_HOME=$absolute_srcdir
-  OCTAVE_LIB_DIR=$absolute_srcdir/scripts
-  OCTAVE_INFO_DIR=$absolute_srcdir/doc
+  case "$builddir" in
+    /*)
+      absolute_builddir=$builddir
+    ;;
+    *)
+      AC_WARN([making builddir absolute -- may lose with automounter])
+      absolute_builddir=`(cd $builddir; pwd)`
+    ;;
+  esac
+  absolute_builddir=$absolute_builddir
+  prefix=$absolute_srcdir
+  infodir=$absolute_srcdir/info
+  fcnfiledir=$absolute_srcdir/scripts
+  archlibdir=$absolute_builddir
+  fcnfilepath='.:$(fcnfiledir)'
 fi
-AC_VERBOSE([setting OCTAVE_HOME to $OCTAVE_HOME])
-AC_VERBOSE([setting OCTAVE_LIB_DIR to $OCTAVE_LIB_DIR])
-AC_VERBOSE([setting OCTAVE_INFO_DIR to $OCTAVE_INFO_DIR])
-AC_SUBST(OCTAVE_HOME)dnl
-AC_SUBST(OCTAVE_LIB_DIR)dnl
-AC_SUBST(OCTAVE_INFO_DIR)dnl
+AC_VERBOSE([setting prefix to $prefix])
+AC_VERBOSE([setting exec_prefix to $exec_prefix])
+AC_VERBOSE([setting bindir to $bindir])
+AC_VERBOSE([setting datadir to $datadir])
+AC_VERBOSE([setting libdir to $libdir])
+AC_VERBOSE([setting includedir to $includedir])
+AC_VERBOSE([setting mandir to $mandir])
+AC_VERBOSE([setting infodir to $infodir])
+AC_VERBOSE([setting fcnfiledir to $fcnfiledir])
+AC_VERBOSE([setting localfcnfilepath to $localfcnfilepath])
+AC_VERBOSE([setting archlibdir to $archlibdir])
+AC_VERBOSE([setting octfiledir to $octfiledir])
+AC_VERBOSE([setting localoctfilepath to $localoctfilepath])
+AC_VERBOSE([setting fcnfilepath to $fcnfilepath])
+AC_SUBST(exec_prefix)
+AC_SUBST(bindir)
+AC_SUBST(datadir)
+AC_SUBST(libdir)
+AC_SUBST(includedir)
+AC_SUBST(mandir)
+AC_SUBST(infodir)
+AC_SUBST(fcnfiledir)
+AC_SUBST(localfcnfilepath)
+AC_SUBST(archlibdir)
+AC_SUBST(octfiledir)
+AC_SUBST(localoctfilepath)
+AC_SUBST(fcnfilepath)
 dnl
 DYNAMIC_LD_OBJ=
 DLD_DIR=
@@ -412,7 +463,7 @@
 dnl
 AC_HAVE_FUNCS(setvbuf getcwd gethostname bzero rindex vfprintf vsprintf)dnl
 AC_HAVE_FUNCS(stricmp strnicmp strcasecmp strncasecmp strerror)dnl
-AC_HAVE_FUNCS(atexit on_exit mktemp)dnl
+AC_HAVE_FUNCS(atexit on_exit tempnam)dnl
 dnl
 dnl Check to see if we have IEEE math functions, and if so, which ones.
 dnl
--- a/octMakefile.in
+++ b/octMakefile.in
@@ -37,6 +37,10 @@
 # Subdirectories to run `make dist' in
 BINDISTSUBDIRS = doc scripts
 
+DIRS_TO_MAKE = $(fcnfiledir) $(octfiledir) $(archlibdir) \
+  `echo $(localfcnfilepath) | awk -F: '{for (i=1; i<=NF; i++) print $i}'` \
+  `echo $(localoctfilepath) | awk -F: '{for (i=1; i<=NF; i++) print $i}'`
+
 all: mkpath
 	for dir in $(SUBDIRS); do echo making $@ in $$dir; cd $$dir; $(MAKE) $@; cd ..; done
 .PHONY: all
@@ -93,6 +97,10 @@
 .PHONY: BUGS.info
 
 install:
+	echo $(DIRS_TO_MAKE)
+	for dir in $(DIRS_TO_MAKE) ; do \
+	  if test -d $$dir ; then true ; else ./mkpath $$dir ; fi ; \
+	done
 	for dir in $(SUBDIRS); do echo making $@ in $$dir; cd $$dir; $(MAKE) $@; cd ..; done
 .PHONY: install
 
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -194,10 +194,23 @@
 defaults.h: defaults.h.in ../Makeconf Makefile
 	@echo "making defaults.h from defaults.h.in"
 	@(sed < $< > $@.tmp \
-	  -e 's;%DEFAULT_PAGER%;\"${DEFAULT_PAGER}\";' \
-	  -e 's;%OCTAVE_HOME%;\"${OCTAVE_HOME}\";' \
-	  -e 's;%OCTAVE_LIB_DIR%;\"${OCTAVE_LIB_DIR}\";' \
-	  -e 's;%OCTAVE_INFO_DIR%;\"${OCTAVE_INFO_DIR}\";')
+	  -e "s;%DEFAULT_PAGER%;\"${DEFAULT_PAGER}\";" \
+	  -e "s;%OCTAVE_PREFIX%;\"${prefix}\";" \
+	  -e "s;%OCTAVE_EXEC_PREFIX%;\"${exec_prefix}\";" \
+	  -e "s;%OCTAVE_DATADIR%;\"${datadir}\";" \
+	  -e "s;%OCTAVE_LIBDIR%;\"${libdir}\";" \
+	  -e "s;%OCTAVE_INFODIR%;\"${infodir}\";" \
+	  -e "s;%OCTAVE_FCNFILEDIR%;\"${fcnfiledir}\";" \
+	  -e "s;%OCTAVE_LOCALFCNFILEPATH%;\"${localfcnfilepath}\";" \
+	  -e "s;%OCTAVE_ARCHLIBDIR%;\"${archlibdir}\";" \
+	  -e "s;%OCTAVE_OCTFILEDIR%;\"${octfiledir}\";" \
+	  -e "s;%OCTAVE_LOCALOCTFILEPATH%;\"${localoctfilepath}\";" \
+	  -e "s;%OCTAVE_FCNFILEPATH%;\"${fcnfilepath}\";" \
+	  -e "s;%TARGET_HOST_TYPE%;\"${target_host_type}\";")
 	@$(top_srcdir)/move-if-change $@.tmp $@
 
+check: all
+.PHONY: check
+
+
 include $(MAKEDEPS)
--- a/src/defaults.h.in
+++ b/src/defaults.h.in
@@ -28,16 +28,52 @@
 #define DEFAULT_PAGER %DEFAULT_PAGER%
 #endif
 
-#ifndef OCTAVE_HOME
-#define OCTAVE_HOME %OCTAVE_HOME%
+#ifndef OCTAVE_PREFIX
+#define OCTAVE_PREFIX %OCTAVE_PREFIX%
+#endif
+
+#ifndef OCTAVE_EXEC_PREFIX
+#define OCTAVE_EXEC_PREFIX %OCTAVE_EXEC_PREFIX%
+#endif
+
+#ifndef OCTAVE_DATADIR
+#define OCTAVE_DATADIR %OCTAVE_DATADIR%
+#endif
+
+#ifndef OCTAVE_LIBDIR
+#define OCTAVE_LIBDIR %OCTAVE_LIBDIR%
+#endif
+
+#ifndef OCTAVE_INFODIR
+#define OCTAVE_INFODIR %OCTAVE_INFODIR%
 #endif
 
-#ifndef OCTAVE_LIB_DIR
-#define OCTAVE_LIB_DIR %OCTAVE_LIB_DIR%
+#ifndef OCTAVE_FCNFILEDIR
+#define OCTAVE_FCNFILEDIR %OCTAVE_FCNFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALFCNFILEPATH
+#define OCTAVE_LOCALFCNFILEPATH %OCTAVE_LOCALFCNFILEPATH%
+#endif
+
+#ifndef OCTAVE_ARCHLIBDIR
+#define OCTAVE_ARCHLIBDIR %OCTAVE_ARCHLIBDIR%
 #endif
 
-#ifndef OCTAVE_INFO_DIR
-#define OCTAVE_INFO_DIR %OCTAVE_INFO_DIR%
+#ifndef OCTAVE_OCTFILEDIR
+#define OCTAVE_OCTFILEDIR %OCTAVE_OCTFILEDIR%
+#endif
+
+#ifndef OCTAVE_LOCALOCTFILEPATH
+#define OCTAVE_LOCALOCTFILEPATH %OCTAVE_LOCALOCTFILEPATH%
+#endif
+
+#ifndef OCTAVE_FCNFILEPATH
+#define OCTAVE_FCNFILEPATH %OCTAVE_FCNFILEPATH%
+#endif
+
+#ifndef TARGET_HOST_TYPE
+#define TARGET_HOST_TYPE %TARGET_HOST_TYPE%
 #endif
 
 #endif
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -64,6 +64,7 @@
 #include "help.h"
 #include "octave.h"
 #include "parse.h"
+#include "defaults.h"
 #include "procstream.h"
 #include "unwind-prot.h"
 #include "octave-hist.h"
@@ -601,6 +602,38 @@
   return retval;
 }
 
+DEFUN ("computer", Fcomputer, Scomputer, 1, 0,
+  "computer ():\n\
+\n\
+Have Octave ask the system, \"What kind of computer are you?\"")
+{
+  Octave_object retval;
+
+  if (args.length () != 1)
+    warning ("computer: ignoring extra arguments");
+
+  ostrstream output_buf;
+
+  if (strcmp (TARGET_HOST_TYPE, "unknown") == 0)
+    output_buf << "Hi Dave, I'm a HAL-9000";
+  else
+    output_buf << TARGET_HOST_TYPE;
+
+  if (nargout == 0)
+    {
+      output_buf << "\n" << ends;
+      maybe_page_output (output_buf);
+    }
+  else
+    {
+      char *msg = output_buf.str ();
+      retval = msg;
+      delete [] msg;
+    }
+
+  return retval;
+}
+
 DEFUN ("flops", Fflops, Sflops, 2, 1,
   "flops (): count floating point operations")
 {
--- a/src/parse.y
+++ b/src/parse.y
@@ -148,6 +148,10 @@
 static tree_expression *make_unary_op (int op, tree_expression *op1,
 				       token *tok_val);
 
+// Make an expression that handles assignment of multiple values.
+static tree_expression *make_multi_val_ret (tree_expression *rhs,
+					    int l = -1, int c = -1);
+
 #define ABORT_PARSE \
   do \
     { \
@@ -163,9 +167,8 @@
 
 %}
 
-/*
- * Bison declarations.
- */
+// Bison declarations.
+
 %union
 {
 // The type of the basic tokens returned by the lexer.
@@ -270,9 +273,8 @@
 // Where to start.
 %start input
 
-/*
- * Grammar rules.
- */
+// Grammar rules.
+
 %%
 
 input		: input1
@@ -689,32 +691,6 @@
 expression	: variable '=' expression
 		  { $$ = new tree_simple_assignment_expression
 		      ($1, $3, 0, 0, $2->line (), $2->column ()); }
-		| '[' screwed_again matrix_row SCREW_TWO '=' expression
-		  {
-
-// Will need a way to convert the matrix list to a list of
-// identifiers.	 If that fails, we can abort here, without losing
-// anything -- no other possible syntax is valid if we've seen the
-// equals sign as the next token after the `]'.
-
-		    $$ = 0;
-		    maybe_screwed_again--;
-		    tree_matrix *tmp = ml.pop ();
-		    tmp = tmp->reverse ();
-		    tree_return_list *id_list = tmp->to_return_list ();
-		    if (id_list)
-		      {
-			$$ = new tree_multi_assignment_expression
-			  (id_list, $6, $5->line (), $5->column ());
-		      }
-		    else
-		      {
-			yyerror ("parse error");
-			error ("invalid identifier list for assignment");
-			$$ = 0;
-			ABORT_PARSE;
-		      }
-		  }
 		| NUM '=' expression
 		  {
 		    yyerror ("parse error");
@@ -722,6 +698,13 @@
 		    $$ = 0;
 		    ABORT_PARSE;
 		  }
+		| '[' screwed_again matrix_row SCREW_TWO '=' expression
+		  {
+		    $$ = make_multi_val_ret ($6, $5->line (), $5->column ());
+
+		    if (! $$)
+		      ABORT_PARSE;
+		  }
 		| simple_expr
 		  { $$ = $1; }
 		;
@@ -1126,6 +1109,8 @@
 
 %%
 
+// Generic error messages.
+
 static void
 yyerror (char *s)
 {
@@ -1165,6 +1150,8 @@
   maybe_page_output (output_buf);
 }
 
+// Error mesages for mismatched end tokens.
+
 static void
 end_error (char *type, token::end_tok_type ettype, int l, int c)
 {
@@ -1193,6 +1180,8 @@
     }
 }
 
+// Check to see that end tokens are properly matched.
+
 static int
 check_end (token *tok, token::end_tok_type expected)
 {
@@ -1228,19 +1217,21 @@
     return 0;
 }
 
-/*
- * Need to make sure that the expression isn't already an identifier
- * that has a name, or an assignment expression.
- *
- * Note that an expression can't be just an identifier anymore -- it
- * must at least be an index expression (see the definition of the
- * non-terminal `variable' above).
- *
- * XXX FIXME XXX.  This isn't quite sufficient.  For example, try the
- * command `x = 4, x' for `x' previously undefined.
- *
- * XXX FIXME XXX -- we should probably delay doing this until eval-time.
- */
+// Try to figure out early if an expression should become an
+// assignment to the builtin variable ans.
+//
+// Need to make sure that the expression isn't already an identifier
+// that has a name, or an assignment expression.
+//
+// Note that an expression can't be just an identifier anymore -- it
+// must at least be an index expression (see the definition of the
+// non-terminal `variable' above).
+//
+// XXX FIXME XXX.  This isn't quite sufficient.  For example, try the
+// command `x = 4, x' for `x' previously undefined.
+//
+// XXX FIXME XXX -- we should probably delay doing this until eval-time.
+
 static tree_expression *
 maybe_convert_to_ans_assign (tree_expression *expr)
 {
@@ -1266,6 +1257,9 @@
     }
 }
 
+// Maybe print a warning if an assignment expression is used as the
+// test in a logical expression.
+
 static void
 maybe_warn_assign_as_truth_value (tree_expression *expr)
 {
@@ -1277,6 +1271,8 @@
     }
 }
 
+// Build a binary expression.
+
 static tree_expression *
 make_binary_op (int op, tree_expression *op1, token *tok_val,
 		tree_expression *op2)
@@ -1355,6 +1351,8 @@
   return new tree_binary_expression (op1, op2, t, l, c);
 }
 
+// Build a prefix expression.
+
 static tree_expression *
 make_prefix_op (int op, tree_identifier *op1, token *tok_val)
 {
@@ -1378,6 +1376,8 @@
   return new tree_prefix_expression (op1, t, l, c);
 }
 
+// Build a postfix expression.
+
 static tree_expression *
 make_postfix_op (int op, tree_identifier *op1, token *tok_val)
 {
@@ -1401,6 +1401,8 @@
   return new tree_postfix_expression (op1, t, l, c);
 }
 
+// Build a unary expression.
+
 static tree_expression *
 make_unary_op (int op, tree_expression *op1, token *tok_val)
 {
@@ -1429,3 +1431,59 @@
 
   return new tree_unary_expression (op1, t, l, c);
 }
+
+// Make an expression that handles assignment of multiple values.
+
+static tree_expression *
+make_multi_val_ret (tree_expression *rhs, int l, int c) 
+{
+// Convert the matrix list to a list of identifiers.  If that fails,
+// we can abort here, without losing anything -- no other possible
+// syntax is valid if we've seen the equals sign as the next token
+// after the `]'. 
+
+  tree_expression *retval = 0;
+
+  maybe_screwed_again--;
+
+  tree_matrix *tmp = ml.pop ();
+
+  tmp = tmp->reverse ();
+
+  tree_return_list *id_list = tmp->to_return_list ();
+
+  if (id_list)
+    {
+      int list_len = id_list->length ();
+
+      if (list_len == 1)
+	{
+	  tree_index_expression *lhs = id_list->remove_front ();
+	  retval = new tree_simple_assignment_expression (lhs, rhs, l, c);
+	  
+	}
+      else if (list_len > 1)
+	{
+	  if (rhs->is_multi_val_ret_expression ())
+	    {
+	      tree_multi_val_ret *t = (tree_multi_val_ret *) rhs;
+	      retval = new tree_multi_assignment_expression (id_list, t, l, c);
+	    }
+	  else
+	    {
+	      yyerror ("parse error");
+	      error ("RHS must be an expression that can return\
+ multiple values");
+	    }
+	}
+      else
+	panic_impossible ();
+    }
+  else
+    {
+      yyerror ("parse error");
+      error ("invalid identifier list for assignment");
+    }
+
+  return retval;
+}
--- a/src/pt-exp-base.cc
+++ b/src/pt-exp-base.cc
@@ -141,13 +141,6 @@
   return tree_constant ();
 }
 
-Octave_object
-tree_expression::eval (int print, int nargout, const Octave_object& args)
-{
-  panic ("invalid evaluation of generic expression");
-  return Octave_object ();
-}
-
 // General matrices.  This list type is much more work to handle than
 // constant matrices, but it allows us to construct matrices from
 // other matrices, variables, and functions.
@@ -590,6 +583,15 @@
     os << ")";
 }
 
+// A base class for objects that can be return multiple values
+
+tree_constant
+tree_multi_val_ret::eval (int print)
+{
+  panic ("invalid evaluation of generic expression");
+  return tree_constant ();
+}
+
 // A base class for objects that can be evaluated with argument lists.
 
 tree_constant
@@ -1468,15 +1470,6 @@
     os << ")";
 }
 
-// Assignment expressions.
-
-tree_constant
-tree_assignment_expression::eval (int print)
-{
-  panic ("invalid evaluation of generic expression");
-  return tree_constant ();
-}
-
 // Simple assignment expressions.
 
 tree_simple_assignment_expression::~tree_simple_assignment_expression (void)
--- a/src/pt-exp-base.h
+++ b/src/pt-exp-base.h
@@ -115,6 +115,9 @@
 
   ~tree_expression (void) { }
 
+  virtual int is_multi_val_ret_expression (void) const
+    { return 0; }
+
   virtual int is_identifier (void) const
     { return 0; }
 
@@ -132,9 +135,6 @@
 
   virtual tree_constant eval (int print) = 0;
 
-  virtual Octave_object eval (int print, int nargout,
-			      const Octave_object& args);
-
 protected:
   type etype;
 };
@@ -185,20 +185,34 @@
   tree_matrix *next;
 };
 
+// A base class for objects that can be return multiple values
+
+class
+tree_multi_val_ret : public tree_expression
+{
+public:
+  tree_multi_val_ret (int l = -1, int c = -1) : tree_expression (l, c) { }
+
+  int is_multi_val_ret_expression (void) const
+    { return 1; }
+
+  tree_constant eval (int print);
+
+  virtual Octave_object eval (int print, int nargout,
+			      const Octave_object& args) = 0;
+};
+
 // A base class for objects that can be evaluated with argument lists.
 
 class
-tree_fvc : public tree_expression
+tree_fvc : public tree_multi_val_ret
 {
 public:
-  tree_fvc (int l = -1, int c = -1) : tree_expression (l, c) { }
+  tree_fvc (int l = -1, int c = -1) : tree_multi_val_ret (l, c) { }
 
   virtual int is_constant (void) const
     { return 0; }
 
-//  virtual int is_builtin (void) const
-//    { return 0; }
-
   virtual tree_constant assign (tree_constant& t, const Octave_object& args);
 
   virtual char *name (void) const
@@ -292,17 +306,17 @@
 // Index expressions.
 
 class
-tree_index_expression : public tree_expression
+tree_index_expression : public tree_multi_val_ret
 {
  public:
-  tree_index_expression (int l = -1, int c = -1) : tree_expression (l, c)
+  tree_index_expression (int l = -1, int c = -1) : tree_multi_val_ret (l, c)
     {
       id = 0;
       list = 0;
     }
 
   tree_index_expression (tree_identifier *i, int l = -1, int c = -1)
-    : tree_expression (l, c)
+    : tree_multi_val_ret (l, c)
       {
 	id = i;
 	list = 0;
@@ -310,7 +324,7 @@
 
   tree_index_expression (tree_identifier *i, tree_argument_list *lst,
 			 int l = -1, int c = -1)
-    : tree_expression (l, c)
+    : tree_multi_val_ret (l, c)
       {
 	id = i;
 	list = lst;
@@ -495,28 +509,10 @@
   tree_expression *op2;
 };
 
-// Assignment expressions.
-
-class
-tree_assignment_expression : public tree_expression
-{
-public:
-  tree_assignment_expression (int l = -1, int c = -1)
-    : tree_expression (l, c)
-    { etype = tree_expression::assignment; }
-
-  ~tree_assignment_expression (void) { }
-
-  tree_constant eval (int print);
-
-  int is_assignment_expression (void) const
-    { return 1; }
-};
-
 // Simple assignment expressions.
 
 class
-tree_simple_assignment_expression : public tree_assignment_expression
+tree_simple_assignment_expression : public tree_expression
 {
  public:
   void init (int plhs, int ans_assign)
@@ -531,14 +527,14 @@
 
   tree_simple_assignment_expression (int plhs = 0, int ans_assign = 0,
 				     int l = -1, int c = -1)
-    : tree_assignment_expression (l, c)
+    : tree_expression (l, c)
       { init (plhs, ans_assign); }
 
   tree_simple_assignment_expression (tree_identifier *i,
 				     tree_expression *r,
 				     int plhs = 0, int ans_assign = 0,
 				     int l = -1, int c = -1)
-    : tree_assignment_expression (l, c)
+    : tree_expression (l, c)
       {
 	init (plhs, ans_assign);
 	lhs = i;
@@ -549,7 +545,7 @@
 				     tree_expression *r,
 				     int plhs = 0, int ans_assign = 0,
 				     int l = -1, int c = -1)
-    : tree_assignment_expression (l, c)
+    : tree_expression (l, c)
       {
 	init (plhs, ans_assign);
 	lhs = idx_expr->ident ();
@@ -567,6 +563,9 @@
 
   tree_constant eval (int print);
 
+  int is_assignment_expression (void) const
+    { return 1; }
+
   void eval_error (void);
 
   void print_code (ostream& os);
@@ -582,11 +581,11 @@
 // Multi-valued assignment expressions.
 
 class
-tree_multi_assignment_expression : public tree_assignment_expression
+tree_multi_assignment_expression : public tree_multi_val_ret
 {
  public:
   tree_multi_assignment_expression (int l = -1, int c = -1)
-    : tree_assignment_expression (l, c)
+    : tree_multi_val_ret (l, c)
       {
 	etype = tree_expression::multi_assignment;
 	lhs = 0;
@@ -594,9 +593,9 @@
       }
 
   tree_multi_assignment_expression (tree_return_list *lst,
-				    tree_expression *r,
+				    tree_multi_val_ret *r,
 				    int l = -1, int c = -1)
-    : tree_assignment_expression (l, c)
+    : tree_multi_val_ret (l, c)
       {
 	etype = tree_expression::multi_assignment;
 	lhs = lst;
@@ -609,13 +608,16 @@
 
   Octave_object eval (int print, int nargout, const Octave_object& args);
 
+  int is_assignment_expression (void) const
+    { return 1; }
+
   void eval_error (void);
 
   void print_code (ostream& os);
 
  private:
   tree_return_list *lhs;
-  tree_expression *rhs;
+  tree_multi_val_ret *rhs;
 };
 
 // Colon expressions.
--- a/src/schur.cc
+++ b/src/schur.cc
@@ -68,7 +68,7 @@
 
       if (error_state)
 	{
-	  error ("schur: expecting string as third argument");
+	  error ("schur: expecting string as second argument");
 	  return retval;
 	}
     }
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -261,34 +261,83 @@
 static char *
 octave_home (void)
 {
-#ifdef RUN_IN_PLACE
-  static char *home = OCTAVE_HOME;
-  return home;
-#else
-  static char *home = 0;
-  delete [] home;
   char *oh = getenv ("OCTAVE_HOME");
-  if (oh)
-    home = strsave (oh);
+
+  return (oh ? oh : OCTAVE_PREFIX);
+}
+
+static char *
+subst_octave_home (char *s)
+{
+  char *home = octave_home ();
+  char *prefix = OCTAVE_PREFIX;
+
+  char *retval;
+
+  if (strcmp (home, prefix) == 0)
+    retval = strsave (s);
   else
-    home = strsave (OCTAVE_HOME);
-  return home;
-#endif
+    {
+      int len_home = strlen (home);
+      int len_prefix = strlen (prefix);
+
+      int count = 0;
+      char *ptr = s;
+      while (strstr (ptr, prefix))
+	{
+	  ptr += len_prefix;
+	  count++;
+	}
+
+      int grow_size = count * (len_home - len_prefix);
+
+      int len_retval = strlen (s) + grow_size;
+
+      retval = new char [len_retval+1];
+
+      char *p1 = s;
+      char *p2 = p1;
+      char *pdest = retval;
+
+      for (int i = 0; i < count; i++)
+	{
+	  p2 = strstr (p1, prefix);
+	  
+	  if (! p2)
+	    panic_impossible ();
+
+	  if (p1 == p2)
+	    {
+	      memcpy (pdest, home, len_home);
+	      pdest += len_home;
+	      p1 += len_prefix;
+	    }
+	  else
+	    {
+	      int len = (int) (p2 - p1);
+	      memcpy (pdest, p1, len);
+	      pdest += len;
+	      p1 += len;
+	    }
+
+	}
+    }
+
+  return retval;
 }
 
 static char *
 octave_info_dir (void)
 {
-#ifdef RUN_IN_PLACE
-  static char *oi = OCTAVE_INFO_DIR;
-  return oi;
-#else
-  static char *oi = 0;
-  delete [] oi;
-  char *oh = octave_home ();
-  oi = strconcat (oh, "/info/");
-  return oi;
-#endif
+  static char *retval = subst_octave_home (OCTAVE_INFODIR);
+  return retval;
+}
+
+static char *
+octave_arch_lib_dir (void)
+{
+  static char *retval = subst_octave_home (OCTAVE_ARCHLIBDIR);
+  return retval;
 }
 
 static char *
@@ -312,18 +361,8 @@
 char *
 octave_lib_dir (void)
 {
-#ifdef RUN_IN_PLACE
-  static char *ol = OCTAVE_LIB_DIR;
-  return ol;
-#else
-  static char *ol = 0;
-  delete [] ol;
-  char *oh = octave_home ();
-  char *tmp = strconcat (oh, "/lib/octave/");
-  ol = strconcat (tmp, version_string);
-  delete [] tmp;
-  return ol;
-#endif
+  static char *retval = subst_octave_home (OCTAVE_LIBDIR);
+  return retval;
 }
 
 // Handle OCTAVE_PATH from the environment like TeX handles TEXINPUTS.
@@ -340,12 +379,7 @@
   static char *pathstring = 0;
   delete [] pathstring;
 
-  static char *std_path = 0;
-  delete [] std_path;
-
-  char *libdir = octave_lib_dir ();
-
-  std_path = strconcat (".:", libdir);
+  static char *std_path = subst_octave_home (OCTAVE_FCNFILEPATH);
 
   char *oct_path = getenv ("OCTAVE_PATH");