[comp.sources.amiga] v91i082: cc - UNIX compatable

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (04/10/91)

Submitted-by: david@starsoft.hou.tx.us (Dave Lowrey)
Posting-number: Volume 91, Issue 082
Archive-name: utilities/cc/part01

[ includes uuencoded executable  ...tad ]

cc is a UNIX compatable, as much as possible, C compiler front end. It
uses flags that are the same as the UNIX version. It also filters
out all of the  SAS/Lattice copyright messages!!!

The original version of this program was witten by Fred Fish, and appeared
on Fish disk #2.

It was then modified by Miles Bader (bader+@andrew.cmu.edu).

David Lowrey, from Starsoft Computing, fixed some more bugs, and added
SAS/C support.

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  README README.DWL builtins.make cc.doc src src/Makefile
#   src/cc.c src/common.h src/config.h src/dstr.c src/dstr.h src/err.c
#   src/list.c src/list.h src/op.c src/op.h src/options.c
#   src/options.h
# Wrapped by tadguy@ab20 on Wed Apr 10 10:48:57 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(421 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XSimple changes to cc's defaults can be made in config.h.  If you make a not-
Xso-simple change, to implement some new feature, please send me back the
Xchanges.  My email address is bader+@andrew.cmu.edu.
X
XThe Makefile and builtins.make (which goes in s: and defines default rules)
Xare for the version of make that comes with pcc 3.0 (although I just noticed,
Xit's ignoring time-stamps!  Anyone got a better make?)
X
X-Miles
END_OF_FILE
if test 421 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'README.DWL' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.DWL'\"
else
echo shar: Extracting \"'README.DWL'\" \(297 characters\)
sed "s/^X//" >'README.DWL' <<'END_OF_FILE'
XApril, 1991
X 
X I have modified cc to fix several errors.
X  
X  I have also modified it to work with SAS/C 5.10. It still works with
X  earlier Lattice Compilers.
X  
XSee the source (sections marked with a /* DWL */) for further details.
X
XThe makefile now works with lmk.
X 
XDave Lowrey
Xdavid@starsoft
END_OF_FILE
if test 297 -ne `wc -c <'README.DWL'`; then
    echo shar: \"'README.DWL'\" unpacked with wrong size!
fi
chmod +x 'README.DWL'
# end of 'README.DWL'
fi
if test -f 'builtins.make' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'builtins.make'\"
else
echo shar: Extracting \"'builtins.make'\" \(54 characters\)
sed "s/^X//" >'builtins.make' <<'END_OF_FILE'
XCC=cc
X
X.SUFFIXES: .c .o
X
X.c.o:
X	${CC} -c ${CFLAGS} $<
END_OF_FILE
if test 54 -ne `wc -c <'builtins.make'`; then
    echo shar: \"'builtins.make'\" unpacked with wrong size!
fi
# end of 'builtins.make'
fi
if test -f 'cc.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cc.doc'\"
else
echo shar: Extracting \"'cc.doc'\" \(4251 characters\)
sed "s/^X//" >'cc.doc' <<'END_OF_FILE'
X	CC: a unix-like compiler driver for amiga lattice-c (that also
X	    filters out stupid messages!). Now works with SAS/C as well.
X
X    USAGE:
X	cc [args] file...
X
X      Arguments are ([x] means x is optional):
X
X	file		A file to compile or link.  Currently, only .c and .o
X			are understood, although supporting .s files would
X			probably be pretty simple.
X
X	-o execfile	Write the resulting executable to EXECFILE (only
X			meaningful when linking).
X
X	-c		Don't link the object file, just leave it there.
X
X	-g[num]		Compile in debugging info, using debug-level NUM.
X	-O		Use the global optimizer (incompatible with -g).
X	-P		Just pre-process the file, creating a .pp file.
X
X	-l libname	Add LIBNAME.lib to the list of libraries.
X
X	-I dir		Add the directory DIR to the path searched for include
X			files.
X	-D define	Add DEFINE a pre-processor define; it can be just a name
X			or name=value.
X	-U undefin	Undefine the symbol UNDEFINE (this really doesn't work).
X	-L libdir	Add the directory LIBDIR to the path searched for
X			libraries.
X	-B bindir	Add the directory BINDIR to the path searched for
X			binaries.
X
X	-px string	Put STRING on the command line of compiler pass X, where
X			X is one of: 1-- pass1; 2-- pass2; o-- optimizer;
X			and l-- linker.  This switch can be used to get at
X			compiler features that cc doesn't directly support,
X			although it'd be better to just add the feature to cc
X			(it shouldn't be too hard)-- and send the change
X			back to me (bader+@andrew.cmu.edu)!
X
X	-t tempdir	Use TEMPDIR as the place to put temporary files.
X
X	+ansi			Enforce ansi fascism.
X	+cpp			Compat with c++.
X	+trad			Use traditional style cpp.
X
X	+[no-]abs-code		Use long (absolute) addressing for function
X				calls.
X	+[no-]abs-data		Use long (absolute) addressing for data.
X
X	+[no-]reload-a4		Reload reg a4 in each function.
X	+[no-]short-ints	Use short integers.
X	+[no-]reg-args		Use register argument passing.
X	+[no-]long-align	Align everything to long boundaries.
X	+[no-]stack-check	Put stack-checking into the func prolog.
X	+[no-]pure-strings	Put strings in the text segment.
X
X	+ffp			Use motorola fast floating point.
X	+881			Compile for a 68881.
X	+ieee			Ieee floating point.
X
X	+68k			Compile for a 68000 and up.
X	+020			Compile for a 68020 and up.
X	+030			Compile for a 68030.
X
X	+[no-]detach		Make a program that runs in the background.
X	+[no-]tiny-main		Use tinymain (this doesn't work).
X	+[no-]resident		Try and make resident-able.
X	+[no-]catch		Compile in code to try and catch exceptions.
X
X	+[no-]optimize		Optimize the obj module.
X	+[no-]link		Link the object modules.
X	+[no-]compile		(Otherwise, just pre-process).
X	+[no-]assemble		Emit object-modules (else assembly).
X	+[no-]debug		Produce debugging info.
X
X	+[no-]echo		Echo what we execute.
X	+[no-]filter		Filter out yucky message from passes.
X	+[no-]exec		Actually run each pass.
X
X	+[no-]big-lc1		Run lc1b instead of lc1.
X
X    DEFAULTS:
X        The default options are: +compile +link +stack-check +exec +filter
X
X	The default output file is "a.out".
X
X	The default temp directory is "t:".
X
X	The default debug level when just -g (or +debug) is specified is 3.
X
X	The default libraries are: "-lc", "-lamiga".
X
X    NOTES:
X	The library -lm is replaced by whichever math library is appropiate
X	given other switches (like +ieee or +ffp), and -lc is replaced by
X	the appropiate c library-- so be and sure to pass the same set of
X	switches to cc when linking as you do when compiling (with -c) the
X	object files!
X
X	This version of cc is intended for use with lattice c version 5.
X
X    BUGS:
X	I haven't nearly tested all the possible combinations of options.
X
X	The libraries supplied by lattice aren't complete, so some combos
X	of switches may not be possible (e.g., +reg-args and +ieee-- lattice
X	doesn't supply a libieeer.lib, and so linking fails in this case).
X
X	-U doesn't work.
X
X	-S doesn't work (and isn't ever likely too unless lattice makes
X	omd a much better program).
X
X	Compiling .s (assembly) files isn't implemented, even though it's
X	probably pretty simple, using asm.  I just never needed it...
X
X    AUTHOR:
X	Miles Bader (bader+@andrew.cmu.edu)
X	   from an earlier program by Fred Fish.
X	   
X	Modified by: Starbound Computing - David Lowrey, programmer.
X		(david@starsoft.hou.tx.us)
X		
END_OF_FILE
if test 4251 -ne `wc -c <'cc.doc'`; then
    echo shar: \"'cc.doc'\" unpacked with wrong size!
fi
chmod +x 'cc.doc'
# end of 'cc.doc'
fi
if test ! -d 'src' ; then
    echo shar: Creating directory \"'src'\"
    mkdir 'src'
fi
if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile'\"
else
echo shar: Extracting \"'src/Makefile'\" \(545 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
XDEBUG=	-O
XOPTS=	+no-stack-check -c
XFLAGS=	$(DEBUG) $(OPTS)
XCFLAGS= $(FLAGS) $(DEFINES)
XLFLAGS= $(FLAGS)
XCC=cc
XLIBS=
X
XTARGET= cc
XOBJS=	cc.o list.o dstr.o err.o op.o options.o
X
X$(TARGET):      $(OBJS)
X	${CC} -o $(TARGET) $(OBJS) $(LIBS)
X
Xcc.o:	list.h dstr.h op.h options.h config.h common.h
X	${CC} ${CFLAGS} cc.c
Xoptions.o: options.h common.h
X	${CC} ${CFLAGS} options.c
Xdstr.o: dstr.h common.h
X	${CC} ${CFLAGS} dstr.c
Xlist.o: list.h common.h
X	${CC} ${CFLAGS} list.c
Xop.o: op.h common.h
X	${CC} ${CFLAGS} op.c
Xerr.o: common.h
X	${CC} ${CFLAGS} err.c
END_OF_FILE
if test 545 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
chmod +x 'src/Makefile'
# end of 'src/Makefile'
fi
if test -f 'src/cc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/cc.c'\"
else
echo shar: Extracting \"'src/cc.c'\" \(25379 characters\)
sed "s/^X//" >'src/cc.c' <<'END_OF_FILE'
X/*
X * cc -- unix-like compiler driver for amiga lattice c
X *
X * adapted for lattice version 5.0 and extensively modified
X *   by Miles Bader, from the original by Fred Fish (copyright
X *   follows).
X *
X * Modified 8/29/90 by The Starbound Software Group, Dave Lowrey - programmer.
X *   The invocation of blink used the explicit path name of blink's
X *   executable (i.e. usr:lc/bin/blink) instead of relying on PATH (as is
X *   done with all of the other commands, such as lc1). I changed the
X *   code to just specify 'BLINK'. This simplifies things when making BLINK
X *   resident.
X *
X *   Made the '-g' option add the ADDSYM parameter to the blink
X *   command line (cpr can guru the system if the executable wasn't linked
X *   with ADDSYM).
X *
X *	Moved the "-m" flag to the lc2 command. It was incorrectly placed on the
X *	lc1 command line.
X *
X *	Fixed to work with SAS/C as well as Lattice/C
X *
X */
X
X/************************************************************************
X *                                                                      *
X *                      Copyright (c) 1985, Fred Fish                   *
X *                          All Rights Reserved                         *
X *                                                                      *
X *      This software and/or documentation is released into the         *
X *      public domain for personal, non-commercial use only.            *
X *      Limited rights to use, modify, and redistribute are hereby      *
X *      granted for non-commercial purposes, provided that all          *
X *      copyright notices remain intact and all changes are clearly     *
X *      documented.  The author makes no warranty of any kind with      *
X *      respect to this product and explicitly disclaims any implied    *
X *      warranties of merchantability or fitness for any particular     *
X *      purpose.                                                        *
X *                                                                      *
X ************************************************************************
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
X#include <dos.h>
X#include <proto/dos.h>
X#include <ios1.h> /* magic */
X
X#include "common.h"
X#include "list.h"
X#include "dstr.h"
X#include "op.h"
X#include "options.h"
X
X#include "config.h"
X
Xstatic char *locate(char *file,struct list *list);      /* find a file */
Xstatic void cleanObjects(int mustExist);        /* Remove .o for link and go mode */
Xstatic int makeObjs();                  /* Reduce to list of object files */
Xstatic int parseCommandLine();          /* Deal with command line */
Xstatic int compile(struct op *op);      /* Translate from .c to .o */
Xstatic int assemble(struct op *op);     /* Translate from .s to .o */
Xstatic int link();                      /* Gather .o's into executable */
Xstatic int runCmd(struct dstr *cmd);
X
X#ifdef amiga
X#define CHECK_ABORT chkabort()
X#else
X#define CHECK_ABORT                             /* NULL expansion */
X#endif  /* amiga */
X
XDBUG_GLOBALS
X
X/*
X *      flags set by command line arguments
X */
Xstatic int debugLevel=DEFAULT_DEBUGLEVEL;       /* -g (debugging level) */
X
Xstruct list *libDirs=NULL;
Xstruct list *incDirs=NULL;
Xstruct list *binDirs=NULL;
Xstruct list *defines=NULL;
Xstruct list *undefines=NULL;
Xstruct list *libs=NULL;
X
Xstruct list *pass1PassThrus=NULL;
Xstruct list *pass2PassThrus=NULL;
Xstruct list *optPassThrus=NULL;
Xstruct list *linkPassThrus=NULL;
X
Xstruct list *ops=NULL;
X
Xstatic char *outfile=DEFAULT_EXEC;      /* output file name from linker */
Xstatic char *tempDir=TEMPDIR;           /* where to keep quad files */
Xstatic char *sinkFile=SINKFILE;         /* where to put output from passes */
X
Xstruct dstr *cmdLine=NULL;
X
Xstatic int abortmsg()
X{
X    if(options_IsSet(OPT_ECHO))
X        fprintf(stderr,"cc: aborting\n");
X    return 1; /* abort */
X}
X
Xstatic int cleanup(status)
Xint status;
X{
X    if(cmdLine!=NULL)   dstr_Free(cmdLine);
X
X    if(libDirs!=NULL)   list_Free(libDirs);
X    if(incDirs!=NULL)   list_Free(incDirs);
X    if(binDirs!=NULL)   list_Free(binDirs);
X    if(defines!=NULL)   list_Free(defines);
X    if(undefines!=NULL) list_Free(undefines);
X    if(libs!=NULL)      list_Free(libs);
X
X    if(pass1PassThrus!=NULL)    list_Free(pass1PassThrus);
X    if(pass2PassThrus!=NULL)    list_Free(pass2PassThrus);
X    if(optPassThrus!=NULL)      list_Free(optPassThrus);
X    if(linkPassThrus!=NULL)     list_Free(linkPassThrus);
X
X    if(ops!=NULL)       list_Free(ops);
X
X    return status;
X}
X
Xstatic void init()
X{
X    int *opt;
X
X    options_Init();
X    for(opt=defaultOptions; *opt!=0; opt++)
X        options_Set(*opt);
X
X    cmdLine=dstr_Create(30);            /* global command buffer */
X
X    libDirs=list_Create((void **)libDirsInit);
X    incDirs=list_Create((void **)incDirsInit);
X    binDirs=list_Create((void **)binDirsInit);
X    defines=list_Create((void **)definesInit);
X    undefines=list_Create((void **)undefinesInit);
X    libs=list_Create((void **)libsInit);
X
X    pass1PassThrus=list_Create(NULL);
X    pass2PassThrus=list_Create(NULL);
X    optPassThrus=list_Create(NULL);
X    linkPassThrus=list_Create(NULL);
X
X    ops=list_Create(NULL);
X    list_SetFree(ops,op_Free);
X}
X
Xvoid main(argc, argv)
Xint argc;
Xchar *argv[];
X{
X    int status;
X
X    DBUG_ENTER("main");
X
X    onexit(cleanup);
X    init();
X
X    onbreak(abortmsg);
X
X    if(parseCommandLine(argc,argv)==0)
X        fatal("no files specified");
X
X    cleanObjects(FALSE);        /* get rid of existing object files if any */
X
X    status=makeObjs();
X    if(status==0 && options_IsSet(OPT_LINK)){
X        status=link();
X        if(list_GetLen(ops)==1)
X            cleanObjects(TRUE);
X    }
X
X    exit(status);
X}
X
X/*
X *      The following macro is used to allow optional whitespace between
X *      an option and it's argument.  Argp is left pointing at the option
X *      and argv and argc are adjusted accordingly if necessary.
X *
X *      Note that there is no check for missing option arguments.  In
X *      particular, -o -V will blindly take -V as the output file name.
X *
X */
X
X#define XARG(argc,argv,argp) {if(*++argp=='\0'){argp=(*argv++);argc--;}}
X
Xstatic int parseCommandLine(argc,argv)
Xint argc;
Xchar **argv;
X{
X    register char *argp;
X
X    DBUG_ENTER("parseCommandLine");
X
X    argc--;
X    argv++;
X    while(argc-- > 0){
X        CHECK_ABORT;
X
X        argp=*argv++;
X
X        if(*argp=='+')
X            options_SetByName(argp+1);
X        else if(*argp!='-')
X            list_Add(ops,(void *)op_Create(argp));
X        else
X            switch(*++argp){
X                case 'c':
X                    options_Clear(OPT_LINK);    /* don't link object modules */
X                    break;
X                case 'p':                       /* pass thru args to a pass */
X                    switch(*++argp){
X                        case '1':               /* pass 1 */
X                            XARG(argc,argv,argp);
X                            list_Add(pass1PassThrus,argp);
X                            break;
X                        case '2':               /* pass 2 */
X                            XARG(argc,argv,argp);
X                            list_Add(pass2PassThrus,argp);
X                            break;
X                        case 'o':               /* optimizer */
X                            XARG(argc,argv,argp);
X                            list_Add(optPassThrus,argp);
X                            break;
X                        case 'l':               /* linking */
X                            XARG(argc,argv,argp);
X                            list_Add(linkPassThrus,argp);
X                            break;
X                        default:
X                            fatal("unknown pass '%c'; must be one of [12ol]",argp[-1]);
X                    }
X                    break;
X                case 'D':
X                    XARG(argc,argv,argp);
X                    list_Add(defines,(void *)argp);
X                    break;
X                case 'E':
X                    warning("-E unimplemented, converted to -P instead");
X                    /* fall through */
X                case 'P':
X                    options_Clear(OPT_COMPILE);
X                    options_Clear(OPT_ASSEMBLE);
X                    options_Clear(OPT_LINK);
X                    break;
X                case 'g':
X                    if(*++argp!='\0') /* optional debuggin level */
X                        debugLevel=atoi(argp);
X                    options_Set(OPT_DEBUG);
X                    break;
X                case 'I':
X                    XARG(argc,argv,argp);
X                    list_Add(incDirs,(void *)argp);
X                    break;
X                case 'l':
X                    XARG(argc,argv,argp);
X                    list_Add(libs,(void *)argp);
X                    break;
X                case 'L':
X                    XARG(argc,argv,argp);
X                    list_Add(libDirs,(void *)argp);
X                    break;
X                case 'B':
X                    XARG(argc,argv,argp);
X                    list_Add(binDirs,(void *)argp);
X                    break;
X                case 'O':
X                    options_Set(OPT_OPTIMIZE);
X                    break;
X                case 'o':
X                    XARG(argc,argv,argp);
X                    outfile=argp;
X                    break;
X                case 't':               /* warning, non-standard */
X                    XARG(argc,argv,argp);
X                    tempDir=argp;
X                    break;
X                case 'S':
X                    warning("-S option not yet implemented, ignored");
X                    options_Clear(OPT_ASSEMBLE);
X                    break;
X                case 'U':
X                    XARG(argc,argv,argp);
X                    list_Add(undefines,(void *)argp);
X                    break;
X                default:
X                    fatal("unknown option '%c'",*argp);
X                    break;
X            }
X    }
X
X    DBUG_RETURN(int,list_GetLen(ops));
X}
X
X/*
X *      For each operand, do compilation or assembly as necessary, to
X *      reduce to an object file in the current directory.
X */
Xstatic int makeObjs()
X{
X    int n;
X    void **els;
X    int numOps=list_GetLen(ops);
X    int status=0;
X
X    DBUG_ENTER("makeObjs");
X
X    for(n=numOps,els=list_GetEls(ops); n>0; n--,els++){
X        struct op *op=(struct op *)*els;
X
X        CHECK_ABORT;
X
X        if(numOps>1 && (op_IsC(op) || op_IsS(op)))
X            printf("%s.%s:\n",op->rootname,op->suffix);
X
X        if(op_IsC(op))
X            status=compile(op);
X        else if(op_IsS(op))
X            status=assemble(op);
X    }
X
X    DBUG_RETURN(int,status);
X}
X
X/* handy little routine */
Xvoid addfList(ds,fmt,list)
Xstruct dstr *ds;
Xchar *fmt;
Xstruct list *list;
X{
X    int n;
X    void **els;
X
X    for(n=list_GetLen(list),els=list_GetEls(list); n>0; n--,els++)
X        dstr_Addf(ds,fmt,(char *)*els);
X}
X
X/*
X *      Note that commands to cc of the form "-l<name>" get interpreted
X *      to mean use a library called "name.lib" from the library
X *      directory.
X *      -lm is specially interpreted to be the appropriate math library.
X */
Xstatic int link()
X{
X    int n;
X    void **els;
X
X    DBUG_ENTER("link");
X
X    dstr_Clear(cmdLine);
X/* Change 'blink' command invocation to use normal PATH search DWL */
X/*    dstr_Addf(cmdLine,"%s ",locate("blink",binDirs)); */  /* DWL */
X    dstr_Addf(cmdLine,"blink  ");							/* DWL */
X
X    if(options_IsSet(OPT_DETACH))
X        dstr_Append(cmdLine,locate("cback.o",libDirs));
X    else if(options_IsSet(OPT_RESIDENT)){
X        if(options_IsSet(OPT_CATCH))
X            dstr_Append(cmdLine,locate("catchres.o",libDirs));
X        else
X            dstr_Append(cmdLine,locate("cres.o",libDirs));
X    }else if(options_IsSet(OPT_CATCH))
X        dstr_Append(cmdLine,locate("catch.o",libDirs));
X    else
X        dstr_Append(cmdLine,locate("c.o",libDirs));
X
X    for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
X        struct op *op=(struct op *)*els;
X        char *name=(op_IsO(op) ? op->rootname : op->basename);
X
X        dstr_Addf(cmdLine,"+%s.o",name);
X    }
X
X    if(options_IsSet(OPT_TINYMAIN))
X        dstr_Addf(cmdLine," define __main=__tinymain ");
X
X    dstr_Addf(cmdLine," library ");
X    for(n=list_GetLen(libs),els=list_GetEls(libs); n>0; n--,els++){
X        char buffer[50];
X        char *lib=(char *)*els;
X
X        if(strcmp(lib,"m")==0){
X            /* map -lm to appropiate library */
X
X            strcpy(buffer,"lib:lcm");
X
X            if(options_IsSet(OPT_FFP))
X                strcat(buffer,"ffp");
X            else if(options_IsSet(OPT_IEEE))
X                strcat(buffer,"ieee");
X            else if(options_IsSet(OPT_881))
X                strcat(buffer,"881");
X
X            /*
X             * there are only r and s libraries for lcm.lib in the lattice
X             * distribution; if there is a way to get the lcmieee, lcmffp,
X             * & lcm881 libraries to work with reg-args & short-ints, I
X             * couldn't find it.
X             */
X            if(options_IsSet(OPT_SHORTINTS))
X                strcat(buffer,"s");
X            if(options_IsSet(OPT_REGARGS))
X                strcat(buffer,"r");
X
X            strcat(buffer,".lib");
X        }else if(strcmp(lib,"lc")==0){
X            /* do the standard c library */
X
X            strcpy(buffer,"lib:lc");
X
X            if(options_IsSet(OPT_SHORTINTS))
X                strcat(buffer,"s");
X            if(options_IsSet(OPT_REGARGS))
X                strcat(buffer,"r");
X            if(options_IsSet(OPT_ABSDATA))
X                strcat(buffer,"nb");
X
X            strcat(buffer,".lib");
X
X            if(options_IsSet(OPT_REGARGS)){
X                /*
X                 * Now, do it AGAIN, but without registers, to catch any missing refs.
X                 * I don't think this is exactly the right thing to do, but there seem
X                 * to be internal functions missing from the register-fied libraries
X                 */
X
X                strcat(buffer,"+lib:lc");
X
X                if(options_IsSet(OPT_SHORTINTS))
X                    strcat(buffer,"s");
X                if(options_IsSet(OPT_ABSDATA))
X                    strcat(buffer,"nb");
X
X                strcat(buffer,".lib");
X            }
X        }else{
X            sprintf(buffer,"%s.lib",lib);
X            strcpy(buffer,locate(buffer,libDirs));
X        }
X
X        if(n==1)
X            dstr_Append(cmdLine,buffer);
X        else
X            dstr_Addf(cmdLine,"%s+",buffer);
X    }
X
X    if(outfile==NULL)
X        /* there better be at least one source file! */
X        outfile=((struct op *)list_GetEls(ops))->basename;
X/* For some reason, this doesn't work with SAS/C 5.10          */
X/* It isn't really needed, as there is no map file produced DWL */
X/*    dstr_Addf(cmdLine," to %s map nil:",outfile); */  /* DWL */
X    dstr_Addf(cmdLine," to %s",outfile);
X    											/* DWL */
X    if(options_IsSet(OPT_DEBUG))				/* DWL */
X    	dstr_Append(cmdLine, " ADDSYM ");		/* DWL */
X
X    addfList(cmdLine," %s",linkPassThrus);
X
X    DBUG_RETURN(int,runCmd(cmdLine));
X}
X
X/*
X *      compile one operand from a C source program to an object module.
X */
Xstatic int compile(op)
Xstruct op *op;
X{
X    int status=0;
X
X    DBUG_ENTER("compile");
X
X    if(options_IsSet(OPT_ASSEMBLE)){
X        status=pass1(op);
X        if(status==0 && options_IsSet(OPT_COMPILE)){
X            CHECK_ABORT;
X            if(options_IsSet(OPT_OPTIMIZE))
X                status=optimize(op);
X            if(status==0)
X                status=pass2(op);
X        }
X    }
X
X    DBUG_RETURN(int,status);
X}
X
X/*
X *      Note that because of brain-damage in the fact that -p to lc1 removes
X *      all predefined defs, we must add them so replacing -c with -P in the
X *      cc command line will result in the same set of predefined symbols.
X *      This is rather ugly and leaves a hole for future problems if we
X *      get out of sync with respect to what names the compiler predefines.
X */
Xstatic int pass1(op)
Xregister struct op *op;
X{
X    char tmpFile[MAXPATH];
X    int status;
X    int n;
X    void **els;
X
X    DBUG_ENTER("pass1");
X
X    dstr_Clear(cmdLine);
X
X    dstr_Append(cmdLine,locate((options_IsSet(OPT_BIGLC1) ? "lc1b" : "lc1"),binDirs));
X
X    if(options_IsSet(OPT_DEBUG)){
X        dstr_Addf(cmdLine," -d%d",debugLevel);
X        if(options_IsSet(OPT_OPTIMIZE)){
X            warning("-g incompatible with -O, -O turned off");
X            options_Clear(OPT_OPTIMIZE);
X        }
X    }
X
X    if(options_IsSet(OPT_FFP))
X        dstr_Addf(cmdLine," -ff");
X    else if(options_IsSet(OPT_881))
X        dstr_Addf(cmdLine," -f8");
X    else if(options_IsSet(OPT_IEEE))
X        dstr_Addf(cmdLine," -fi");
X    else
X        dstr_Addf(cmdLine," -fl");
X
X    if(options_IsSet(OPT_SHORTINTS))
X        dstr_Addf(cmdLine," -w");
X    if(options_IsSet(OPT_LONGALIGN))
X        dstr_Addf(cmdLine," -l");
X/*                                     Moved this to lc2
X    if(options_IsSet(OPT_020))
X        dstr_Addf(cmdLine," -m2");
X    else if(options_IsSet(OPT_030))
X        dstr_Addf(cmdLine," -m3");
X*/
X    if(options_IsSet(OPT_CATCH) && !options_IsSet(OPT_ABSDATA)){
X        warning("+catch implies +abs-data");
X        options_Set(OPT_ABSDATA);
X    }
X
X    dstr_Addf(cmdLine," -b%d",options_IsSet(OPT_ABSDATA) ? 0 : 1);
X    dstr_Addf(cmdLine," -r%d",options_IsSet(OPT_ABSCODE) ? 0 : 1);
X
X    if(options_IsSet(OPT_REGARGS))
X        dstr_Addf(cmdLine,"r"); /* part of -r switch */
X
X    {
X        char buf[15], *p=buf;
X
X        if(options_IsSet(OPT_ANSI))             *p++='a';
X        if(options_IsSet(OPT_CPP))              *p++='+';
X        if(options_IsSet(OPT_TRAD))             *p++='l', *p++='o';
X        if(options_IsSet(OPT_REGARGS))          *p++='r';
X        if(options_IsSet(OPT_PURESTRINGS))      *p++='s';
X
X        if(p>buf){
X            *p='\0';
X            dstr_Addf(cmdLine," -c%s",buf);
X        }
X    }
X
X    if(options_IsSet(OPT_COMPILE)){
X        strcpy(tmpFile,tempDir);
X        strcat(tmpFile,op->basename);
X        strcat(tmpFile,".q");
X        dstr_Addf(cmdLine," -o%s",tmpFile);
X    }else{
X        strcpy(tmpFile,op->basename);
X        strcat(tmpFile,".pp");
X
X        dstr_Addf(cmdLine," -o%s -p",tmpFile);
X    }
X
X    for(n=list_GetLen(undefines),els=list_GetEls(undefines); n>0; n--,els++){
X        /*************************
X        dstr_Addf(cmdLine," -u%s",(char *)*els);
X        **************************/
X        warning("-U%s ignored! (unimplemented)",(char *)*els);
X    }
X
X    addfList(cmdLine," -d%s",defines);
X    addfList(cmdLine," %s",pass1PassThrus);
X
X    for(n=list_GetLen(incDirs),els=list_GetEls(incDirs); n>0; n--,els++){
X        char *id=(*els);
X        int len=strlen(id);
X
X        dstr_Addf(cmdLine," -i%s",*els);
X
X        if(len>0 && id[len-1]!=':' && id[len-1]!='/')
X            dstr_Addf(cmdLine,"/");
X    }
X
X    dstr_Addf(cmdLine," %s",op->rootname);
X
X    status=runCmd(cmdLine);
X    if(status==0 && options_IsSet(OPT_EXEC) && !readable(tmpFile))
X        status=1;
X
X    DBUG_RETURN(int,status);
X}
X
X/* run the optimizer */
Xstatic int optimize(op)
Xstruct op *op;
X{
X    DBUG_ENTER("optimize");
X
X    dstr_Clear(cmdLine);
X    dstr_Addf(cmdLine,"%s %s%s",locate("go",binDirs),tempDir,op->basename);
X
X    addfList(cmdLine," %s",optPassThrus);
X
X    DBUG_RETURN(int,runCmd(cmdLine));
X}
X
X/*
X *      Run second pass of compiler on a single operand.
X */
Xstatic int pass2(op)
Xstruct op *op;
X{
X    char objFile[MAXPATH];
X    int status;
X
X#ifdef DBUG
X    fprintf(stderr,"Entering pass2...\n");
X#endif
X
X    DBUG_ENTER("pass2");
X
X    dstr_Clear(cmdLine);
X
X    dstr_Append(cmdLine,locate("lc2",binDirs));
X
X    if(!options_IsSet(OPT_STACKCHECK))
X        dstr_Addf(cmdLine," -v");
X
X/* Moved -m from lc1 to lc2 (The lattice doc doesn't say WHERE it goes!) DWL */
X
X    if(options_IsSet(OPT_020))			/* DWL */
X        dstr_Addf(cmdLine," -m2");		/* DWL */
X    else if(options_IsSet(OPT_030))		/* DWL */
X        dstr_Addf(cmdLine," -m3");		/* DWL */
X
X    strcpy(objFile,op->basename);
X    strcat(objFile,".o");
X
X    dstr_Addf(cmdLine," -o%s",objFile);
X
X    dstr_Addf(cmdLine," %s%s",tempDir,op->basename);
X
X    addfList(cmdLine," %s",pass2PassThrus);
X
X    status=runCmd(cmdLine);
X    if(status==0 && options_IsSet(OPT_EXEC) && !readable(objFile))
X        status=1;
X
X    DBUG_RETURN(int,status);
X}
X
X/*
X *      I have not yet had occasion to use the macro assembler,so this
X *      part is not yet implemented.  If anyone wants to send me the
X *      appropriate code, I will be glad to install it.
X */
Xstatic int assemble(op)
Xstruct op *op;
X{
X    DBUG_ENTER("assemble");
X    warning("assembly pass not yet implemented");
X    DBUG_RETURN(int,1);
X}
X
Xstatic void filteredOutputFrom(source,filter)
XFILE *source;
Xchar **filter;
X{
X    char buf[200];
X
X    DBUG_ENTER("FilteredOutputFrom");
X
X    while(!feof(source)){
X        char **ignore;
X
X        fgets(buf,sizeof(buf),source);
X
X        for(ignore=filter; *ignore!=NULL; ignore++)
X            if(strncmp(*ignore,buf,strlen(*ignore))==0)
X                break;
X
X        if(*ignore==NULL)
X            fputs(buf,stdout);
X    }
X
X    DBUG_VOID_RETURN;
X}
X
X#ifdef AMIGA
X
Xstatic int execToFile(cmd,sink)
Xchar *cmd;
XFILE *sink;
X{
X    /* this is a dopey version that uses Execute, since I can't get fork to work */
X    long fh;
X
X    DBUG_ENTER("execToFile");
X
X    if(sink==NULL)
X        fh=0;
X    else
X        fh=chkufb(fileno(sink))->ufbfh;
X
X    DBUG_RETURN(int,Execute(cmd,0L,fh)!=(-1));
X
X#if 0
X    char *argv[50],**argp=argv;
X    struct ProcID child;
X    static struct FORKENV env={0,0,0,0,0,NULL};
X    int i;
X
X    DBUG_ENTER("execToFile");
X
X    if(cmd==NULL)
X        DBUG_RETURN(int,1);
X
X    /* this is sort of stupid, cause forkv will just put them back together,
X     * but oh well...
X     */
X    *argp=strtok(cmd," \t");
X    while(*argp!=NULL)
X        *++argp=strtok(NULL," \t");
X
X    if(sink==NULL)
X        env.std_out=0;
X    else{
X        struct UFB *ufb=chkufb(fileno(sink));
X        int i;
X
X        printf("argv[%d]:",argp-argv);
X        for(argp=argv;*argp!=NULL;argp++)
X            printf(" %s",*argp);
X        putchar('\n');
X
X        printf("env: %d, %d, %d, %d, %d, %d\n",
X                env.priority, env.stack, env.std_in, env.std_out,
X                env.console, env.msgport);
X
X        printf("ufb==0x%x, fh==0x%x, go? ",ufb,ufb->ufbfh);
X
X        fflush(stdout);
X
X        env.std_out=ufb->ufbfh; /* magic to get amigados handle from FILE */
X    }
X
X    if((i=forkv(argv[0],argv,&env,&child))==-1){
X        poserr("forkv");
X        DBUG_RETURN(int,1);
X    }
X
X    printf("Fork returns: %d\n",i);
X
X    DBUG_RETURN(int,wait(&child));
X#endif
X}
X
X#endif
X
Xstatic int runCmd(cmd)
Xstruct dstr *cmd;
X{
X    int status;
X    char *buf=dstr_GetBuf(cmd);
X
X    DBUG_ENTER("RunCommand");
X
X    DBUG_3("cmd","execute '%s'",buf);
X    if(options_IsSet(OPT_ECHO)){
X        puts(buf);
X        fflush(stdout);
X    }
X
X    CHECK_ABORT;
X
X    if(options_IsSet(OPT_EXEC)){
X        FILE *sink;
X
X        if(sinkFile!=NULL && options_IsSet(OPT_FILTER)){
X            sink=fopen(sinkFile,"w+");
X            if(sink==NULL)
X                perror(sinkFile);
X        }else
X            sink=NULL;
X
X        status=execToFile(buf,sink);
X        DBUG_3("sys","subcommand returns status %d",status);
X
X        if(sink!=NULL){
X            rewind(sink);
X            filteredOutputFrom(sink,filteredPrefixes);
X            fclose(sink);
X            unlink(sinkFile);
X        }
X
X        DBUG_RETURN(int,status);
X    }else
X        DBUG_RETURN(int,0);
X}
X
X/*
X *      Look through the list of paths pointed to by "vec" until we find
X *      a file with name given pointed to by "namep".  If none is found,
X *      the name pointed to by namep is returned.
X */
Xstatic char *locate(name,paths)
Xchar *name;
Xstruct list *paths;
X{
X    static char namebuf[MAXPATH];
X    void **els;
X    int n;
X
X    DBUG_ENTER("locate");
X
X    if(strchr(name,':')!=NULL || *name=='/')
X        return name;    /* absolute */
X
X    for(n=list_GetLen(paths),els=list_GetEls(paths); n>0; n--,els++){
X        int len=strlen((char *)*els);
X
X        strcpy(namebuf,(char *)*els);
X        if(len>0 && namebuf[len-1]!=':' && namebuf[len-1]!='/')
X            strcat(namebuf,"/");
X        strcat(namebuf,name);
X
X        DBUG_3("try","look for '%s'",namebuf);
X        if(readable(namebuf)){
X            name=namebuf;
X            break;
X        }
X    }
X
X    DBUG_RETURN(char *,name);
X}
X
X/*
X *      Check to see if the file exists and is readable.
X */
Xstatic int readable(name)
Xchar *name;
X{
X    register int status=0;
X    register long fildes;
X
X    DBUG_ENTER("readable");
X
X#ifdef unix
X    fildes=open(name,O_RDONLY);
X    if(fildes >= 0){
X        (void) close(fildes);
X        status=1;
X    }
X#else
X    fildes=Lock(name,ACCESS_READ);
X    if(fildes != 0){
X        UnLock(fildes);
X        status=1;
X    }
X#endif
X
X    DBUG_RETURN(int,status);
X}
X
X/*
X *      If an executable is made from a single C file, the normal behavior
X *      for the unix environment is to treat the .o file as an intermediate
X *      file and remove it, so we follow suit.
X */
Xstatic void cleanObjects(mustExist)
Xint mustExist;
X{
X    int n;
X    void **els;
X
X    DBUG_ENTER("cleanObjects");
X
X    for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
X        char buf[MAXPATH];
X        struct op *op=(struct op *)*els;
X
X        if(!op_IsO(op)){
X            strcpy(buf,op->basename);
X            strcat(buf,".o");
X            if(unlink(buf)!=0 && mustExist)
X                warning("can't delete '%s'",buf);
X        }
X    }
X
X    DBUG_VOID_RETURN;
X}
END_OF_FILE
if test 25379 -ne `wc -c <'src/cc.c'`; then
    echo shar: \"'src/cc.c'\" unpacked with wrong size!
fi
chmod +x 'src/cc.c'
# end of 'src/cc.c'
fi
if test -f 'src/common.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/common.h'\"
else
echo shar: Extracting \"'src/common.h'\" \(450 characters\)
sed "s/^X//" >'src/common.h' <<'END_OF_FILE'
X/* comment out the following define to turn off debugging dumps */
X#define DBUG_ENTER(x)
X#define DBUG_RETURN(x,y) return(y)
X#define DBUG_VOID_RETURN return
X#define DBUG_2(x,y)
X#define DBUG_3(x,y,z)
X#define DBUG_4(w,x,y,z)
X#define DBUG_GLOBALS
X
X#include <string.h>
X#include <stdlib.h>
X
X/* #include "dbug.h" */
X
X#define NEW(t) ((t *)malloc(sizeof(t)))
X#define FREE(x) free((char *)x)
X
X#ifndef NULL
X#define NULL 0
X#endif
X
X#define TRUE 1
X#define FALSE 0
END_OF_FILE
if test 450 -ne `wc -c <'src/common.h'`; then
    echo shar: \"'src/common.h'\" unpacked with wrong size!
fi
chmod +x 'src/common.h'
# end of 'src/common.h'
fi
if test -f 'src/config.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/config.h'\"
else
echo shar: Extracting \"'src/config.h'\" \(2101 characters\)
sed "s/^X//" >'src/config.h' <<'END_OF_FILE'
X/*
X * configuration file for cc; easily re-configurable stuff goes here.
X * March 1989, Miles Bader
X *
X * Modified 1/29/91 by The Starbound Software Group, Dave Lowrey - programmer. 
X *	Modified to work with SAS/C as well as Lattice/C
X */
X
X/*
X * this file contains declarations, so it can only be included in one source file
X */
X
X#define MAXPATH 200		/* max length of a path */
X
X/* What to call executable if not specified.  If NULL, named after 1st source file */
X#define DEFAULT_EXEC "a.out"
X 
X/* must be a prefix; i.e., needs a slash or a colon on the end */
X#define TEMPDIR	"T:"		/* Keep intermediate files in temp directory */
X/* #define TEMPDIR "" */	/* Keep intermediate files in current dir */
X
X/* The file for filtering compiler pass output.  If NULL, no filtering is done */
X#define SINKFILE "T:__cc_sink"
X
X#define DEFAULT_DEBUGLEVEL 3	/* default debug level if just -g is given */
X
X/* Listf of default options.  Note that not having _EXEC, _COMPILE, _ASSEMBLE,
X * and _LINK set by default would be very wierd
X */
Xint defaultOptions[]={
X    OPT_COMPILE,	/* compile things! */
X    OPT_ASSEMBLE,	/* make object files! */
X    OPT_EXEC,		/* execute passes! */
X    OPT_LINK,		/* link into executable! */
X    OPT_FILTER,		/* filter out obnoxious messages */
X    OPT_STACKCHECK,	/* enable stack checking */
X    0
X};
X
X/* initial contents of some lists; &insertMark is where additional elements go */
Xchar *libDirsInit[]={"",&insertMark,"lib:",NULL};
Xchar *incDirsInit[]={&insertMark,"include:",NULL};
Xchar **binDirsInit=NULL;
Xchar **definesInit=NULL;
Xchar **undefinesInit=NULL;
Xchar *libsInit[]={&insertMark,"lc","amiga",NULL};
X
X/* prefixes that are filtered out of the compiler output stream */
Xchar *filteredPrefixes[]={
X    "\n",			/* blank lines */
X    "Copyright",		/* copyright noticed */
X    "Lattice",			/* lattice advertisements */
X    "SAS",				/* SAS advertisements */       /* DWL */
X
X    /* lc2 */
X    "Module size",
X
X    /* blink */
X    "Blink - Version",
X    "Enter a DEFINE value", 	/* input is impossible anyway... */
X    "BLINK Complete",
X    "Final output file size",
X    NULL
X};
END_OF_FILE
if test 2101 -ne `wc -c <'src/config.h'`; then
    echo shar: \"'src/config.h'\" unpacked with wrong size!
fi
chmod +x 'src/config.h'
# end of 'src/config.h'
fi
if test -f 'src/dstr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dstr.c'\"
else
echo shar: Extracting \"'src/dstr.c'\" \(1491 characters\)
sed "s/^X//" >'src/dstr.c' <<'END_OF_FILE'
X/*
X * dynamic strings
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "dstr.h"
X
Xstruct dstr *dstr_Create(initsize)
Xint initsize;
X{
X    struct dstr *n=NEW(struct dstr);
X    
X    DBUG_ENTER("dstr_Create");
X
X    if(n==NULL)
X	fatal("couldn't allocate a dstr");
X
X    n->buf=malloc(initsize+1);
X
X    if(n->buf==NULL)
X	fatal("couldn't allocate dstr of size %d",initsize);
X
X    n->max=initsize;
X    n->len=0;
X    *n->buf='\0';
X
X    DBUG_RETURN(struct dstr *,n);
X}
X
Xvoid dstr_Free(ds)
Xstruct dstr *ds;
X{
X    DBUG_ENTER("dstr_Free");
X
X    if(ds->buf!=NULL)
X	FREE(ds->buf);
X    FREE(ds);
X
X    DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Clear(ds)
Xstruct dstr *ds;
X{
X   ds->len=0;
X   *ds->buf='\0';
X}
X
Xvoid dstr_Append(ds,str)
Xstruct dstr *ds;
Xchar *str;
X{
X    int len=strlen(str);
X    
X    DBUG_ENTER("dstr_Append");
X
X    if(len+ds->len>ds->max){
X	ds->max+=len+len;
X	ds->buf=(char *)realloc((void *)ds->buf,ds->max);
X
X	if(ds->buf==NULL)
X	    fatal("couldn't extend a dstr to %d chars",ds->max);
X    }
X
X    strcpy(ds->buf+ds->len,str);
X    ds->len+=len;
X
X    DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Set(ds,str)
Xstruct dstr *ds;
Xchar *str;
X{
X    DBUG_ENTER("dstr_Set");
X
X    ds->len=0;
X    dstr_Append(ds,str);
X
X    DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Addf(ds,fmt,a1,a2,a3,a4,a5,a6,a7)
Xstruct dstr *ds;
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X    char buf[500];
X
X    DBUG_ENTER("dstr_Addf");
X
X    sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7);
X
X    DBUG_2("buf",buf);
X
X    dstr_Append(ds,buf);
X
X    DBUG_VOID_RETURN;
X}
END_OF_FILE
if test 1491 -ne `wc -c <'src/dstr.c'`; then
    echo shar: \"'src/dstr.c'\" unpacked with wrong size!
fi
# end of 'src/dstr.c'
fi
if test -f 'src/dstr.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dstr.h'\"
else
echo shar: Extracting \"'src/dstr.h'\" \(293 characters\)
sed "s/^X//" >'src/dstr.h' <<'END_OF_FILE'
X/*
X * dynamic strings
X * March 1989, Miles Bader
X */
X
Xstruct dstr {
X    int max,len;
X    char *buf;
X};
X
Xstruct dstr *dstr_Create();
Xvoid dstr_Free();
Xvoid dstr_Clear();
Xvoid dstr_Set();
Xvoid dstr_Append();
Xvoid dstr_Addf();
X
X#define dstr_GetBuf(d) ((d)->buf)
X#define dstr_GetLen(d) ((d)->len)
END_OF_FILE
if test 293 -ne `wc -c <'src/dstr.h'`; then
    echo shar: \"'src/dstr.h'\" unpacked with wrong size!
fi
# end of 'src/dstr.h'
fi
if test -f 'src/err.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/err.c'\"
else
echo shar: Extracting \"'src/err.c'\" \(613 characters\)
sed "s/^X//" >'src/err.c' <<'END_OF_FILE'
X/*
X * these are in a separate file so the compiler doesn't bitch about mismatched
X * arguments
X */
X
X#include <stdio.h>
X
X#include "common.h"
X
X/*VARARGS1*/
Xvoid warning(fmt,a1,a2,a3,a4,a5,a6,a7)
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X    fputs("cc: warning: ",stderr);
X    fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
X    putc('\n',stderr);
X    (void) fflush(stderr);
X}
X
X/*VARAS1*/
Xvoid fatal(fmt,a1,a2,a3,a4,a5,a6,a7)
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X    fputs("cc: error: ",stderr);
X    fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
X    putc('\n',stderr);
X    (void) fflush(stderr);
X    exit(1);
X}
END_OF_FILE
if test 613 -ne `wc -c <'src/err.c'`; then
    echo shar: \"'src/err.c'\" unpacked with wrong size!
fi
# end of 'src/err.c'
fi
if test -f 'src/list.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/list.c'\"
else
echo shar: Extracting \"'src/list.c'\" \(1886 characters\)
sed "s/^X//" >'src/list.c' <<'END_OF_FILE'
X/*
X * expandable lists
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "list.h"
X
X#define BUMPSIZE 5			/* grow list this much at a time */
X
Xchar insertMark;			/* dummy used for its address */
X
Xstruct list *list_Create(init)
Xvoid **init;
X{
X    void **p,**q;
X    struct list *l=NEW(struct list);
X    
X    DBUG_ENTER("list_Create");
X
X    if(l==NULL)
X	fatal("couldn't allocate a list");
X
X    l->num=0;
X
X    l->insertionPoint=(-1);
X
X    for(p=init; p!=NULL && *p!=NULL; p++)
X	if(*p==&insertMark)
X	    l->insertionPoint=l->num;
X	else
X	    l->num++;
X
X    l->els=(void **)malloc(l->num*sizeof(void *));
X
X    if(l->els==NULL && l->num>0 /* ANSI compat */)
X	fatal("couldn't allocate initial list elements");
X
X    for(p=init,q=l->els; p!=NULL && *p!=NULL; p++)
X	if(*p!=&insertMark)
X	    *q++=(*p);
X
X    l->max=l->num;
X    if(l->insertionPoint<0)
X	l->insertionPoint=l->num; 	/* default is at end */
X
X    l->freeProc=NULL;
X
X    DBUG_RETURN(struct list *,l);
X}
X
Xvoid list_Free(l)
Xstruct list *l;
X{
X    DBUG_ENTER("list_Free");
X
X    if(l->freeProc!=NULL){
X    	void **els;
X	int n;
X	
X	DBUG_4("free","using freeProc on %d els: 0x%x",l->num,l->freeProc);
X
X	for(n=l->num,els=l->els; n>0; n--,els++){
X	    DBUG_3("free","freeProc(0x%x)",*els);
X	    (*l->freeProc)(*els);
X	}
X    }
X
X    if(l->els!=NULL){
X        DBUG_3("free","freeing els: 0x%x",l->els);
X	FREE(l->els);
X    }
X
X    DBUG_3("free","freeing list: 0x%x",l);
X
X    FREE(l);
X
X    DBUG_VOID_RETURN;
X}
X
Xvoid list_Add(l,e)
Xstruct list *l;
Xvoid *e;
X{
X    int i;
X    
X    DBUG_ENTER("list_Add");
X
X    if(l->num>=l->max){
X        l->max+=BUMPSIZE;
X	l->els=(void **)realloc((void *)l->els,l->max*sizeof(void *));
X
X	if(l->els==NULL)
X	    fatal("couldn't extend a list to %d elements",l->max);
X    }
X
X    for(i=l->num; i>l->insertionPoint; i--)
X	l->els[i]=l->els[i-1];
X
X    l->els[l->insertionPoint++]=e;
X
X    l->num++;
X
X    DBUG_VOID_RETURN;
X}
END_OF_FILE
if test 1886 -ne `wc -c <'src/list.c'`; then
    echo shar: \"'src/list.c'\" unpacked with wrong size!
fi
# end of 'src/list.c'
fi
if test -f 'src/list.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/list.h'\"
else
echo shar: Extracting \"'src/list.h'\" \(491 characters\)
sed "s/^X//" >'src/list.h' <<'END_OF_FILE'
X/*
X * expandable lists
X * March 1989, Miles Bader
X */
X
Xextern char insertMark;
X
Xstruct list {
X    int num,max;
X    int insertionPoint;			/* where a new element gets added */
X    void **els;
X    void (*freeProc)();			/* if non-NULL, used to free elements */
X};
X
Xstruct list *list_Create(void **initEls);
Xvoid list_Free(struct list *l);
Xvoid list_Add(struct list *l,void *el);
X
X#define list_GetEls(l) ((l)->els)
X#define list_GetLen(l) ((l)->num)
X
X#define list_SetFree(l,fp) ((l)->freeProc=fp)
END_OF_FILE
if test 491 -ne `wc -c <'src/list.h'`; then
    echo shar: \"'src/list.h'\" unpacked with wrong size!
fi
# end of 'src/list.h'
fi
if test -f 'src/op.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/op.c'\"
else
echo shar: Extracting \"'src/op.c'\" \(1235 characters\)
sed "s/^X//" >'src/op.c' <<'END_OF_FILE'
X/*
X * file operands
X * March 1989, Miles Bader (orig from cc.c by fred fish)
X */
X
X#include "common.h"
X#include "op.h"
X
X/*
X *	Split an operand name into rootname, basename, and suffix
X *	components.  The rootname is the full name, minus any suffix,
X *	but including any prefix.  The basename is the rootname minus
X *	any prefix.  The suffix is anything after the last '.' character.
X *	Only the suffix is allowed to be the null string.
X */
Xstruct op *op_Create(filename)
Xchar *filename;
X{
X    char *split;
X    extern char *strrchr();
X    struct op *op=NEW(struct op);
X
X    DBUG_ENTER("op_Create");
X
X    DBUG_3("ops", "create op '%s'",filename);
X
X    if(op==NULL)
X	fatal("couldn't allocate an op");
X
X    op->rootname=filename;
X
X    split=strrchr(filename,'/');
X    if(split==NULL)
X	split=strrchr(filename,':');
X
X    if(split==NULL)
X	op->basename=filename;
X    else
X	op->basename=++split;
X
X    split=strrchr(filename,'.');
X    if(split==NULL)
X	op->suffix="";
X    else{
X	*split++='\0';
X	op->suffix=split;
X    }
X
X    DBUG_3("ops","rootname '%s'",op->rootname);
X    DBUG_3("ops","basename '%s'",op->basename);
X    DBUG_3("ops","suffix '%s'",op->suffix);
X
X    DBUG_RETURN(struct op *,op);
X}
X
Xvoid op_Free(op)
Xstruct op *op;
X{
X    FREE(op);
X}
END_OF_FILE
if test 1235 -ne `wc -c <'src/op.c'`; then
    echo shar: \"'src/op.c'\" unpacked with wrong size!
fi
# end of 'src/op.c'
fi
if test -f 'src/op.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/op.h'\"
else
echo shar: Extracting \"'src/op.h'\" \(992 characters\)
sed "s/^X//" >'src/op.h' <<'END_OF_FILE'
X/*
X * file operands
X * March 1989, Miles Bader (orig from cc.c by fred fish)
X */
X
X/*
X *	Command line arguments that represent files to be compiled, assembled,
X *	or linked, are kept track of as "ops".  If, for example,
X *	the file name is "df0:mydir/junk.c", then the rootname is
X *	"df0:mydir/junk", the basename is "junk", and the suffix is "c".
X *	String suffixes are used, rather than single character suffixes, to
X *	allow use of names with multicharacter suffixes.
X */
X
Xstruct op{		/* Info about each operand (non option) */
X    char *rootname;		/* Name minus any suffix */
X    char *basename;		/* Name minus any prefix or suffix */
X    char *suffix;		/* suffix of operand */
X};
X
X/*
X *	macros to determine the suffix type of a file given a pointer to
X *	its operand structure.
X */
X#define op_IsC(op) (strcmp(op->suffix,"c")==0)
X#define op_IsS(op) (strcmp(op->suffix,"s")==0)
X#define op_IsO(op) (strcmp(op->suffix,"o")==0)
X
Xstruct op *op_Create(char *name);
Xvoid op_Free(struct op *op);
END_OF_FILE
if test 992 -ne `wc -c <'src/op.h'`; then
    echo shar: \"'src/op.h'\" unpacked with wrong size!
fi
# end of 'src/op.h'
fi
if test -f 'src/options.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/options.c'\"
else
echo shar: Extracting \"'src/options.c'\" \(2271 characters\)
sed "s/^X//" >'src/options.c' <<'END_OF_FILE'
X/*
X * compiler options processing
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "options.h"
X
Xlong globalOpts[MAXOPTS/BITSPERLONG];
X
Xstruct option {
X    char *name;
X    int opt;
X    int *set;
X};
X
X/* pre-processor compatibility modes */
Xint ppOptSet[]={OPT_TRAD, OPT_ANSI, OPT_CPP, 0};
X
X/* cpu-types */
Xint cpuOptSet[]={OPT_68K, OPT_020, OPT_030, 0};
X
X/* types of floating point support */
Xint floatOptSet[]={OPT_FFP, OPT_IEEE, OPT_881, 0};
X
Xstruct option optionlist[]={
X/*   name		mask		excludes	*/
X
X    /* parsing */
X    {"ansi",		OPT_ANSI,	ppOptSet},
X    {"c++",		OPT_CPP,	ppOptSet},
X    {"traditional",	OPT_TRAD,	ppOptSet},
X
X    /* code gen */
X    {"abs-code",	OPT_ABSCODE},
X    {"abs-data",	OPT_ABSDATA},
X
X    {"reg-args",	OPT_REGARGS},
X    {"reload-a4",	OPT_RELOADA4},
X    {"short-ints",	OPT_SHORTINTS},
X    {"long-align",	OPT_LONGALIGN},
X    {"stack-check",	OPT_STACKCHECK},
X
X    {"pure-strings",	OPT_PURESTRINGS},
X
X    {"68k",		OPT_68K,	cpuOptSet},
X    {"020",		OPT_020,	cpuOptSet},
X    {"030",		OPT_030,	cpuOptSet},
X
X    {"881",		OPT_881,	floatOptSet},
X    {"ffp",		OPT_FFP,	floatOptSet},
X    {"ieee",		OPT_IEEE,	floatOptSet},
X
X    /* linking */
X    {"detach",		OPT_DETACH},
X    {"resident",	OPT_RESIDENT},
X    {"tiny-main",	OPT_TINYMAIN},
X    {"catch",		OPT_CATCH},
X
X    {"optimize",	OPT_OPTIMIZE},
X    {"link",		OPT_LINK},
X    {"compile",		OPT_COMPILE},
X    {"assemble",	OPT_ASSEMBLE},
X    {"debug",		OPT_DEBUG},
X
X    {"echo",		OPT_ECHO},
X    {"filter",		OPT_FILTER},
X    {"exec",		OPT_EXEC},
X
X    {"big-lc1",		OPT_BIGLC1},
X
X    NULL
X};
X
Xvoid options_SetByName(optname)
Xchar *optname;
X{
X    struct option *opt;
X    int not=FALSE;
X
X    if(strncmp(optname,"no-",3)==0){
X	optname+=3;
X	not=TRUE;
X    }
X
X    for(opt=optionlist; opt->name!=NULL; opt++)
X	if(strcmp(optname,opt->name)==0){
X	    if(not){
X		if(opt->set!=NULL)
X		    fatal("%s is not a boolean option",opt);
X		else
X		    options_Clear(opt->opt);
X	    }else{
X		if(opt->set!=NULL){
X		    int *clear;
X		    for(clear=opt->set; *clear!=0; clear++)
X		    	options_Clear(*clear);
X		}
X		
X		options_Set(opt->opt);
X	    }
X
X	    break;
X	}
X
X    if(opt->name==NULL)
X	fatal("unknown option: %s",optname);
X}
X
Xvoid options_Init()
X{
X    int i;
X    for(i=0; i<(MAXOPTS/BITSPERLONG); i++)
X	globalOpts[i]=0;
X}
END_OF_FILE
if test 2271 -ne `wc -c <'src/options.c'`; then
    echo shar: \"'src/options.c'\" unpacked with wrong size!
fi
# end of 'src/options.c'
fi
if test -f 'src/options.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/options.h'\"
else
echo shar: Extracting \"'src/options.h'\" \(2277 characters\)
sed "s/^X//" >'src/options.h' <<'END_OF_FILE'
X/*
X * compiler options
X * March 1989, Miles Bader
X */
X
X/* increase this for more options */
X#define MAXOPTS	64
X
X#ifndef BITSPERLONG
X#define BITSPERLONG 32
X#endif
X
Xextern long globalOpts[MAXOPTS/BITSPERLONG];
X
X#define options_IsSet(opt) \
X (globalOpts[(opt)/BITSPERLONG]&(1L<<((opt)%BITSPERLONG)))
X#define options_Set(opt) \
X (globalOpts[(opt)/BITSPERLONG]|=(1L<<((opt)%BITSPERLONG)))
X#define options_Clear(opt) \
X (globalOpts[(opt)/BITSPERLONG]&=~(1L<<(long)((opt)%BITSPERLONG)))
X
Xvoid options_SetByName(char *optname);
Xvoid options_Init();
X
X
X#define OPT_NONE	0
X
X#define OPT_ANSI	1	/* enforce ansi fascism */
X#define OPT_CPP		2	/* compat with c++ */
X#define OPT_TRAD	3	/* use traditional style cpp */
X
X#define OPT_ABSCODE	4	/* use long (absolute) addressing for function calls */
X#define OPT_ABSDATA	5	/* use long (absolute) addressing for data */
X
X#define OPT_RELOADA4	6	/* reload reg a4 in each function */
X#define OPT_SHORTINTS	7	/* use short integers */
X#define OPT_REGARGS	8	/* use register argument passing */
X#define OPT_LONGALIGN	9	/* align everything to long boundaries */
X#define OPT_STACKCHECK	10	/* put stack-checking into the func prolog */
X#define OPT_PURESTRINGS	11	/* put strings in the text segment */
X
X#define OPT_FFP		12	/* use mot fast floating point */
X#define OPT_881		13	/* compile for a 68881 */
X#define OPT_IEEE	14	/* ieee floating point */
X
X#define OPT_68K		15	/* compile for a 68000 and up */
X#define OPT_020		16	/* compile for a 68020 and up */
X#define OPT_030		17	/* compile for a 68030 */
X
X#define OPT_DETACH	18	/* make a program that runs in the background */
X#define OPT_TINYMAIN	19	/* use tinymain (this doesn't work) */
X#define OPT_RESIDENT	20	/* try and make resident-able */
X#define OPT_CATCH	21	/* compile in code to try and catch exceptions */
X
X#define OPT_OPTIMIZE	22	/* optimize the obj module */
X#define OPT_LINK	23	/* link the object modules */
X#define OPT_COMPILE	24	/* (otherwise, just pre-process) */
X#define OPT_ASSEMBLE	25	/* emit object-modules (else assembly) */
X#define OPT_DEBUG	26	/* produce debugging info */
X
X#define OPT_ECHO	27	/* echo what we execute */
X#define OPT_FILTER	28	/* filter out yucky message from passes */
X#define OPT_EXEC	29	/* actually run each pass */
X
X#define OPT_BIGLC1	30	/* run lc1b instead of lc1 */
END_OF_FILE
if test 2277 -ne `wc -c <'src/options.h'`; then
    echo shar: \"'src/options.h'\" unpacked with wrong size!
fi
# end of 'src/options.h'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.misc.