                   ----------------------------
                   PORTING ATP TO NEW PLATFORMS
                   ---------------------------- 

Contact info: Thomas McWilliams

Internet: thomas.mcwilliams@f615.n109.z1.fidonet.org
Fidonet : 1:109/615
RIME    : runninga ->2<-

From time to time I get questions about how to port ATP to some
specific platform. Unless I have access to the compiler on the
target system, I can not always give an exact answer. However,
ATP tries to follow ANSI and POSIX very closely. So the first
step in porting ATP would be to make sure you have an ANSI compliant
compiler. GNU GCC is an excellent choice: it's free, it works,
and ATP likes it. Most Unix systems which are compliant with
System V Release 4.0 should have no problems with the ATP source
tree. 

If for some reason you can not obtain an ANSI compliant C
compiler for your system, you may be able to use a program called
UNPROTO which will convert ANSI code to the older style K&R C.
This program is available via FTP, check with Wietse Venema
(wietse@wzv.win.tue.nl), and also via Mac's Place BBS (919)
891-1111 as UNPROTO4.ZIP. I personally have never used this
program but it is well regarded. If you should use this
successfully with ATP, please share your story with me so that
your tips can be passed on to others.

But even if you have an ANSI compliant compiler, you may be bitten
by inadequate or parochial system libraries. In terms of ATP, you
can make things easy on yourself by insuring that you have the
3 main DIRENT functions for reading directories. They are: opendir(),
readdir(), closedir(). These are part of the POSIX standard. Your
compiler may offer a POSIX compatibility library--check and see.
The DIRENT family of functions is available as an add-on library from
GNU. FTP from prep.ai.mit.edu:/pub/gnu. Mac's Place BBS listed above
may also carry the source for this library. The only functions of
importance are the 3 directory functions mentioned above. Port 
these 3 functions to your system and you will have gone a long way
toward POSIX compliance, and you will be able to easily port many
other softwares to your system.
 
Other problem areas depend on whether your system offers a fork()
call. If in doubt, define USESYSTEM which will spawn processes
via the system() routine. Time functions are also often
non-standard.  ATP prefers utime() for setting times on files.
Your non-Unix system might offer something different which could
be adapted. For instance, the Turbo C++ port of ATP substitutes
Borland's getftime() and setftime() library functions.

Strictly speaking, there should not be a need for much of a
"port" per se.  If your compiler is ANSI compliant then you
should be able to compile ATP. Check ATP's  /etc subdirectory for
various makefiles that have been submitted. These may offer you a
a good starting point. ATP's main makefile works under DMAKE, GNU
MAKE, and Sys V MAKE. As a help in constructing your own
makefile, review the separate DEFINES section of this document for
an overview of some of the relevant ATP preprocessor symbols.

                   --------------------------
                   GENERAL PORTING TECHNIQUES
                   --------------------------
All that being said, there are 3 phases to porting any software:

phase 1: getting the software to compile (i.e. creating object files).
phase 2: getting the object files to link into an executable.
phase 3: getting the executable to run properly. 

Assuming that you have an ANSI compliant compiler, the problems
in phase 1 are usually caused by a difference between header
files or their location in different C implementations.  The
errors given are usually along the lines of "can't find include
file <blah.h>". The initial quick and dirty way to handle this is
to go to the source file that causes this warning and comment out
#include <blah.h>. Then try again. At a later time you can always
go back and figure out what actually should be included for your
system and add the appropriate #ifdefs. Again, I repeat: assuming
an ANSI compiler, the problems with phase 1 almost always have to
do with header files. Note that ATP source wants to see __MSDOS__
defined when compiling under DOS. If your compiler doesn't
predefine this, then by all means define it  at the top of
system.h (i.e.  #define __MSDOS__).

Problems in phase 2 (the link phase) almost always have to do
with resolving symbols. If you are given an unresolved symbol,
check all your system libraries and see if it exists or if a close
cousin exists.  Make sure you link in all relevant libraries.
Grepping your include directories is a quick method for an
initial search for the missing symbol.  Sometimes Borland will
have a function like findfirst() but Microsoft will have the same
function only it will be preceded by an underscore: _findfirst().
If you are unable to find the function in your libraries, you may
have to write your own version. ATP has versions of commonly
missing functions in the file 'system.c'. Check this file and if
you need a function, make sure it is visible during the compile
phase by hacking system.c and system.h so that it will be
available for compilation during phase 1.

Finally, phase 3 involves resolving runtime problems. Common
problems here involve buffering of stream i/o. You may have to
add a setvbuf() or an ffluush(stdout) at a critical point in the
program if text seems not to be displayed properly. Actually
problems in this phase although they may look major, are usually
resolved by just some very slight modification of the original
source. Another source of problems here is a wrongly configured
initialization file. In the case of ATP it is the file 'atprc'.
Make sure all paths and options are correct for your system in
this file.  

---------------------------------------------------------
Description of #define'd MACROS and CONSTANTS used in ATP 
---------------------------------------------------------

Note that these descriptions are just to help get you started,
study the source code itself when in doubt rather than blindly
following these descriptions.

/* the following "NEED" defines are used to supply missing functions */

NEEDREADLINE   /* only if you can't uses the included editline library */
NEEDSTRI       /* only if your system needs stricmp() and strnicmp() */
NEEDTEMPNAM    /* only if you lack tempnam() function in your C library */

/* language and character set dependant defines */

ENGLISH   /* for English language messages */
FRENCH    /* for French language messages */
LATIN1    /* use ISO high ASCII characters */


/* general defines possibly relevant to any operating system */

LOOSE      /* defined for relaxed handling of this:  const char *const foobar */
BADLWR     /* some versions of GCC 1.40 and before have bad touppr() tolwr() */
USESYSTEM  /* if your OS can't fork() and exec() then system() is used */
VT220      /* if your terminal is compatible with VT220 (linux console) */
__HUGE__   /* UNDEFINE this in system.h  if you have 64K segment limits */
GETWD      /* ideally defined 'getcwd' in system.h but it's system dependant */ 
           /* The main problem is that some versions of getcwd() for DOSish */
	   /* systems don't get the drive letter with the path; If you are */
	   /* on a dos/os2/winders system, define this to a version of */
	   /* getcwd() that returns the full path with drive letter; Unix */
	   /* users don't need to worry about this nonsense ...  */
HAVE_SIGINT /* predefined for unix, but others with SIGINT should define this */

/* these are generally already defined for UNIX type systems in system.h */

UNIXCMDS    /* automatically defined in system.h for most unix-type systems */ 
HAVE_UTIME  /* file times can be set with utime() */
HAVE_LINK   /* your file systems support hard links */
USEDIRENT   /* your system has opendir(), readdir(), closedir() */
HAVE_SETGET /* you have tcsetattr() and tcgetattr() */

/* the following are relevant to DOS, WINDOWS, OS2 only */

ADDRIVE     /* predefined as addrive() will prepend drive letter to path */ 
DJD         /* D.J.Delore gcc for ms-dos */
HAVE_FTIME  /* used in qlib.c:fcopy() if you have getftime() setftime() */
            /* used to preserve date/time of copied files, these are avail- */
            /* able under Turbo C++, but what about WIN and MSC?? In any case */
	    /* it is not critical */
__MSDOS__   /* DOS users: you must define this if your compiler doesn't do it */
NEEDISKS    /* msdos getdrive() setdrive() */ 
OS2         /* defined for OS2 */
WIN32       /* for windows (and microsoft C ??) */
 
/* these are for debugging, not needed for most purposes */

ATPDBG      /* define this for general debugging */
ATPDBG2     /* define this for debugging replys in makemail.c */
ATPDBG3     /* define this for debugging chosetag.c:clip() */
ATPDBM      /* only used when debugging with special malloc() library */

/* the following are UNUSED and should be AVOIDED unless you want problems */

NONUM       /* unused don't use this one */ 
LISTDIR     /* unused don't use this one */
ATPUNUSED   /* unused don't use this one */
NEEDSYSTEM  /* unused dont' use this one */
NEEDFIXPATH /* unused (changes '/' to '\' in path string */
SIMP        /* possibly useful if you can't build editline library */

