COMPILING THE PORTABLE FORTH ENVIRONMENT		-*- indented-text -*-
########################################

I tried to make porting easy by using ANSI-C or POSIX features
whereever possible.

Currently the program is tested by myself with these systems:

	- 486DX33 PC running Linux (development platform)
	- 486DX33 PC running FreeBSD
	- 486DX33 PC running MS-DOS 5.0 and OS/2 2.1
	- IBM RS/6000 520H running AIX 3.2
	- IBM PS/2 Model 70 running AIX 1.2
	- HP 9000/730 running HP-UX A.09.01 A
	- DECstation 500/260 with Ultrix 4.3.0 RISC
	- DEC 3000 workstation (alpha) running OSF/1 2.1
		( S" MAX-D" ENVIRONMENT? DROP D.
		  39614081238685424727357390847 ok :-)

Others ran it on SGI with IRIX, SunOS (but not Solaris), DomainOS,
Xenix and other Intel based System V unices.
Any reasonably up to date Unix system with a true ANSI-C compiler
should do it with little changes. Please report any problems, I'll
try to make it easier for you if you do!

A configuration script is provided in src/config.


How to configure and compile on a Unix system:
==============================================

Please read the file `tuning' too.

Overview

1) If your system is one of Linux, FreeBSD, AIX 3.2, AIX 1.2, HP-UX on
   HP 700/800, DEC Ultrix RISC or OSF/1 2.1 on a DEC Alpha:

   Simply change to directory pfexxx/src and type ./config.  This
   makes two important files:

	makefile	contains compiler options and dependencies

	config.h	contains a few #define-d symbols controlling
			the compilation of environmental dependencies.

   Now type make and wait for the compilation to finish. That should
   be all.

2) If your Unix-system is not among those I tried, things are only
   a little more difficult.
   Change to directory pfexxx/src and type ./config. Again this
   generates two files:

	makefile	dependencies and a generic version of
			compiler options

	config.h	#define-d symbols describing your system as
			result of an investigation of your system's
			libraries and header files

   Now check these two files. Change compiler options in makefile for
   best performance with your compiler and machine.

   In the makefile you'll find source files are divided into two
   groups.  The first, larger group contains source files in --
   hopefully -- ANSI-C, including only ANSI-defined header files. The
   second group contains files with environmental dependencies. If
   your make permits it you can use a more strict ANSI-compiler for
   the first (maybe with a command line option -ansi or some other
   means to restrict the name space to ANSI-C features) and a more
   generous for the other.

   config.h may need some overworking since the header files on many
   systems contain quite confusing conditional constructs. Not every-
   thing grep finds in them becomes really declared when they are
   included. On a relatively new system however, config.h is probably
   ok.

   Check config.h for neccessary changes according to the next section
   below. Most important: check if you should set the _BSD-switch.
   Then compile the system with make.

   If you don't seem to have definitions that config finds in your
   header files, then check the header files if these definitions are
   conditional. If they are, define the neccessary symbols to activate
   them. E.g. HP-UX knows very little about it's own library if not
   either
	#define POSIX_SOURCE
     or	#define XOPEN_SOUCE
     or	#define HPUX_SOURCE or or or...
   is given, at best as commandline option -D... in makefile


Options in config.h
-------------------

At the time of this writing, the config script checks for the
following conditions. When you read this, a few more may have been
added. So have a look at what the script tries to do, if you
experience problems you can't solve with these informations:

HAVE_AH_TRIG	define this if your system has asinh, acosh, atanh
		defined in it's -lm library and math.h header.

HAVE_MEMMOVE	define this if your system has memmove() in it's
		library. Else write this prototype in config.h:

		void memmove (char *, const char *, const unsigned);

HAVE_STRDUP	define this if your system has strdup() declared in
		string.h. Else define a prototype like this:

		char *strdup (const char *);

If your system hasn't strerror but has a global variable sys_errlist[],
then define this:

		#define strerror(x) sys_errlist [x]

HAVE_SYS_SIGLIST define this if your system has the global variable
		char *sys_siglist[] containing signal names.

HAVE_ATEXIT	define this if your system has atexit(). Otherwise
		declare like this:

		typedef void (*atexit_fp) (void);
		void atexit (atexit_fp);
		#define exit(X) trick_exit(X)

HAVE_RAISE	define this if your system has the raise() function.
		Otherwise define like this:

		#define raise(X) kill (getpid (), X)

HAVE_REMOVE	define this if your system has remove(), otherwise

		#define remove unlink

HAVE_RENAME	define this if your system has rename(), otherwise
		provide the following prototype:

		int rename (const char *, const char *);

HAVE_TERMCAP	define this if your system has a libtermcap.a.
		If this is used depends on the constant USE_TERMCAP
		described below.

HAVE_TERMIO_H, HAVE_TERMIOS_H, HAVE_TERMCAP_H
		define them if the respective header files are
		available. If both termios.h and termio.h then
		termios.h is used by pfe and defining HAVE_TERMIO_H
		is meaningless.

HAVE_USLEEP	define this, if usleep() is available in your system
HAVE_POLL	define this if you haven't usleep() but have poll()
HAVE_SELECT	define this if you haven't usleep() but have select(),
		pointless if poll() is available.

		If you have none of the three, think of a method to
		wait some milliseconds and rewrite the function
		millisec in `src/sysdep.c'.
		Otherwise the Forth-word MS will perform very poorly.

If your system doesn't define fpos_t, then define like this:

	#define fpos_t long

If your compiler can't handle the const-keyword, define like this:

	#define const


IMPORTANT:
----------
More important options where the config script makes no attempt to
check them out:

_BSD		define this to 1 if your system is BSD-like. It
		triggers a certain handling of the termcap query and a
		slightly different signal handling. SunOS, DomainOS,
		FreeBSD, Ultrix and probably many more systems need
		this switch. If you haven't set this switch on a
		system that needs it, the program dies or hangs
		immediately...

USE_TERMCAP	pfe can use three slightly different methods to
		retrieve information about the connected terminal.

		If USE_TERMCAP is defined then either:
		  - termcap calls to a termcap library
		    (if HAVE_TERMCAP is set, i.e. you have a real
		    termcap library)
		  - termcap calls emulated by a curses library

		depending on the available library. Otherwise
		  - terminfo calls to a curses library.

		If your system has both a termcap and a curses library
		(e.g. Linux), then test which setting yields better
		results.
		If your system has only curses then using the termcap
		emulation in curses instead of terminfo is probably
		pointless.

ISO_CHARSET	the config-script simply defines this symbol because
		most workstations have these ISO characters. If you
		don't see letters here "", then your system
		has no ISO characters or (more likely) your terminal
		connection, your `more' or whoknowswhatelse isn't
		set up to handle 8-Bit characters. If you remove the
		symbol from config.h, pfe takes care not to display
		these characters but a reverse `?'.

OLDCPP		define this if your C-compiler's preprocessor is
		pre-ANSI and can't handle macro arguments padded
		together with ##. You'd probably better switch to
		gcc in that case.

WRONG_SPRINTF	some libraries have sprintf returning the string, not
		the string length as function result (old versions of
		SunOS).  If your system has this feature, define the
		symbol.


Which compiler should be used?
------------------------------

On a unix system with a modern ANSI C compiler this compiler can be
used.  On a RISC-machine the original compiler may be faster than
GNU-C (RS/6000, DEC Ultrix RISC).

If the system vendor's compiler is old and/or buggy and/or produces
slow code, you better switch to gcc. Any gcc will do fine. The eldest
I recently tried was version 1.42.

You can compile pfe with a C++ compiler too (tested with g++).


Which warning level should be used?
-----------------------------------

The source code of pfe passes gcc at the highest warning level with
very few harmless warnings, provided that the header files of the
system are ok. Unfortunately sometimes the system header files don't
pass gcc at this warning level without a lot of noise. Or they compile
ok but lack prototypes they should contain. This leads to warnings
lateron in the pfe source. Reduce the warning level in that case.

If you are forced to do so (by your header files) you can even compile
pfe with gcc -traditional. In this case define like this in config.h:

	#define OLDCPP 1
	#define const

Expect a lot of warnings about incompatible pointers. But it seems to
work (when I tried last time on Linux at least :-).


How to port to a non-Unix system:
=================================

What to do depends on how similar to Unix your system is. If you have
a make-utility, clone `emx/makefile' to your needs. Otherwise refer to
`emx/makefile' to determine wich source files make up the system and
feed them into your compiler's project management. Replace
`term-emx.c' by the terminal driver you write for your system.

Compile`src/check_c.c' with the C-compiler you want to use, run it and
place it's output in a file `src/config.h'.
Read the above section about options in config.h and edit config.h to
describe your system. Refer to your C-compiler's header files.

Write at least one new source file for the terminal stuff. Check
`src/term.h' for which definitions are exported by the terminal driver
and rewrite them from scratch e.g. in a file called `src/term-st.c'
for an Atari. Then set the variable TERM_O in Makefile to your file's
name, e.g. `term-st.o'.
For an example you can refer to `src/termcap.c' (complex),
`src/term-emx.c'(recommended) or `src/curses.c'.


Configuring the Forth system
============================

Besides the options you have to set to make pfe compile on your system
you can configure features of the Forth-system.

Many of these options can be set at startup of pfe on the command
line. Some more options and defaults for these command line options
can be set in the source file `src/options.h'.

You should set convenient defaults at least for

  - search paths for block files and including source
  - your favorite text-file editor
  - the amount of memory the system uses

The system might crash if the default system size or the size for the
stacks is too small. You'll need a stack-size of at least 1024 items
(just a guess :-).

After the program compiled without errors you can test it with the
program `testsuite.4th' by either typing

	make testit
or
	src/pfe testsuite.4th

at the shell prompt.
If it passes these tests it should be pretty much ok!


INSTALLATION
============

The executable file pfe[.exe] is the only file you need to run any ANS
Forth program. It provides all word sets without need to load anything
else. Therefore all you have to install is this executable somewhere
in the search path.

If you want to use online help, refer to the files in the subdirectory
`help' for installation instructions and for how you can contribute to
online help for this and other free Forth systems.

As you see in file `src/options.h', pfe looks for INCLUDED files and
for block files in certain locations. If you choose to install sources
there, they become available from any location in your file system
without path name. Also there are default extensions you won't have to
type when referring to a block file or source text file by name.

Using these features is entirely up to you and your needs/taste. The
makefile has no `install' target creating any directories or copying
any files.

---
End of instructions about compiling and installing pfe.
Hope you like it! -duz



======================================================================
Hints for certain systems follow:
======================================================================

X-Window's xterm vt100 emulator
===============================

I thought I finally learned how to handle cursor keys.
However function keys are often not registered correctly in the
/etc/termcap file which is needed by pfe to retrieve information on
what function keys send.

To fix this check your /etc/termcap for the xterm entry and ensure all
function keys are described correctly. On Linux this requires to add
three lines to /etc/termcap like this:

xterm|vs100|xterm terminal emulator (X window system):\
	...
	:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
+	:kN=\E[6~:kP=\E[5~:kh=\E[7~:kH=\E[8~:\
+	:k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\
+	:k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k0=\E[21~:\
	:pt:sf=\n:sr=\EM:\
	...

But you can verify this on your own system by opening an xterm, then

	vi /etc/termcap

insert the above lines in the proper place and change like this:

	:k1=:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\
cursor here ^

Then type i-^v-F1

If you get something else than

	:k1=[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\

then repeat the step for all function keys added in the above
mentioned three lines. Replace the ^[ by \E, then save it.
Otherwise just type U to undo the change to this line and save the
file.

Vi-clone elvis (on Linux) feels better with this fix too.


Linux
=====

Since pfe was developed on a Linux box, there are no serions problems.

 - On some versions of Linux it was neccessary to issue `stty -ixon'
   before starting pfe. I try to do this setting from inside pfe but
   this fails on these versions. It isn't needed in recent releases.

 - If you want to use the curses-based terminal driver curses.c, then
   you'll have to add a command line option in the makefile:

	OPTS=-I/usr/include/ncurses

 - It's not a good idea to remap xterm's cursor and function keys
   using ~/.Xdefaults or ~/.Xresources like it is sometimes
   recommended in order please `bash' or `less'. These programs should
   better use curses or termcap like any other decent program instead
   of defining their own startup files containing hardwired key
   codes. If more programs relied on it then probably /etc/termcap
   would be in better shape too.

=======================================================================

IRIX SGI installation.
======================

Sean Conner reports the following problem and fix related to SGI
machines:

> NOTE:  There have been some problems with the SGI port. If you are
> compiling the system under IRIX 4.0.1 and using the supplied C compiler,
> then you have to define SGIFIX.  Any later release, or using gcc, will
> avoid this problem.			spc@pineal.math.fau.edu

(diffs to pfe-0.8.6)

=====Makefile=====
89a90,96
>   #####################################################
>   # Due to a compiler bug in 4.0.1, if you use 4.0.1 cc
>   # then you need to use the line with -DSGIFIX.  This is
>   # ONLY WITH CC UNDER 4.0.1.  If you are using gcc, then
>   # you don't need the fix.	spc@pineal.math.fau.edu
>   ######################################################
> 
90a98,103
>   # CC =	cc
>   # CC = 	gcc
>   CC =		cc -DSGIFIX
>   OPTIMIZE =	-O
>   DEBUG =	-g
>   STRICT =
=====support.c=====
169a170,187
> /*******************************************************************
> * NOTE: Because of a compiler bug in 4.0.1 of the SGI C compiler,
> * 	This stupid little routine has to be included for u_d_mul()
> *	to work properly.  This bug, is of course, fixed for 4.0.5,
> *	but we (where I work) can't afford to get the upgrade (at least
> *	yet), so this patch is here for that.
> *	
> *	But, if you have gcc running under 4.0.1, it will compile this
> *	correctly, so you don't need the fix in that case.  Since I
> *	really don't like gcc all that much, I need to use this.
> *
> *			spc@pineal.math.fau.edu
> *********************************************************************/
> 
> #ifdef SGIFIX
>   void sgifix(uCell hi,uCell lo) { uCell c1 = hi; uCell c2 = lo; }
> #endif
> 
178a197,199
> #       ifdef SGIFIX
> 	  sgifix(ud->hi,ud->lo);
> #	endif

======================================================================

HP-UX
=====

I never saw a C-compiler by HP with optimization not broken. You can
use the lowest optimization +O1 at first, this works on the systems I
have access to. +O2 and -O don't work (you get an error-message when
typing return in pfe). gcc -O2 is faster than c89 +O1 but c89 +O2
would probably again be faster than gcc -- if it only worked.

Again due to a compiler bug you must remove the const-keyword in the
parameter list of function wild_words() in dictnry.c and in the header
file support.h to compile with HP's compiler.

Since pfe starting with releas 0.9.8 supports the global register
feature of gcc this compiler should be used anyway.

======================================================================

Ultrix
======

The system's compiler compiles pfe fine. But it behaves strangely when
it comes to floating point exceptions. I don't know why, use gcc and
benefit from global register variables!

Add `#define HAVE_SELECT 1' to `src/config.h' by hand or `MS' will
resort to sleeping at least 1 sec...

======================================================================

Sun
===

Solaris 2.3 on a Sparc workstation:
-----------------------------------

pfe compiles without errors or warnings using gcc or a C++ beast by
Sun called CC supplied as part of a development platform (we don't
have Sun's ANSI-C compiler here). Unfortunately it doesn't run.
And after a few hours of digging with gdb I still don't have the
faintest idea what's going wrong. Any hint is appreciated.

SunOS
-----

there are reports that it runs on elder versions of Sun's OS (maybe on
other machines than Sparc?).  If you succeed please let me know.
