COMPILING THE PORTABLE FORTH ENVIRONMENT
########################################

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

Currently the program is tested by myself with these systems:

	- Linux
	- FreeBSD 1.1 Release
	- MS-DOS with emx
	- AIX 3.2.5 and AIX 1.2
	- HP-UX on 9000/7xx
	- Ultrix RISC 4.3.1

"Tested" means: It compiles, the result runs the testsuite and the
tetris demo without problems.

Others ran it on SGI with IRIX, SunOS, Solaris, DomainOS, Xenix, Intel
based System VR3 systems and OS/2. Any reasonably up to date Unix
system with a true ANSI-C compiler should do it with almost no
change. 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:
==============================================

Overview

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

   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's 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 makefile you find source files are divided into two groups.
   The first, larger group contains source files in pure ANSI-C,
   including only ANSI-defined header files. The second group contains
   files with a few environmental dependencies. You can specify two
   different compilers for the two kinds of sources: A paranoid ANSI-C
   compiler for the first, a compiler knowing a little more about
   your system for the second.

   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_TERMIO_H, HAVE_TERMIOS_H, HAVE_TERMCAP_H
		define them if the respective header files are
		available. If both termios.h and termio.h are
		available, define HAVE_TERMIOS_H.

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()

If you have neither 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. This
		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...

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 (SunOS).
		If your system has this feature, define the symbol.


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

On a unix box with a modern ANSI C compiler this compiler can be used.
On a RISC-machine the original compiler may be faster than GNU-C
(rs6000, 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 (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 makefile.emx to your needs. Otherwise refer to
makefile.emx 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 section above
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' or `src/curses.c'
(recommended).


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/const.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. 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.

As you see in file `src/const.h', pfe looks for INCLUDED files and for
block files in certain locations. If you choose to install any 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 refering to such a 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
===============================

Nothing special any more. I finally learned how to handle this
correctly.


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 first have to set up your /usr/include a little:
	cd /usr/include
	mv curses.h curses-old.h
	ln -s ncurses/* .

-duz
=======================================================================

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 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.

-duz
======================================================================

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.
