[net.micro.atari] cc for dev. package

bammi@cwruecmp.UUCP (Jwahar R. Bammi) (01/17/86)

	You asked for source, you get source. This is a useful utility
for use with the developers package from Atari.
				
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	cc.doc
#	cc.c
#	getopt.c
#	syserr.c
# This archive created: Fri Jan 17 04:42:24 1986
# By:	Jwahar R. Bammi ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'cc.doc'" '(5567 characters)'
if test -f 'cc.doc'
then
	echo shar: over-writing existing file "'cc.doc'"
fi
sed 's/^X//' << \SHAR_EOF > 'cc.doc'
Xcc - Compile C programs
X
X	cc [options] ... file ...
X
XCc runs the various passes of the C compiler, followed by the assembler
Xand the linker and relmod to produce an executable image.
X
XCc accepts various types of `file' arguements. Files with a `.c'
Xextension are compiled and assembled to produce object files with the
X`.o' extension. Files with `.s' extensions are assembled to produce
Xobject files with `.o' extensions. File with `.o' extensions are
Xincluded in the list of files to be linked, in the position in which
Xthey occur in the list of files. File names with no extension, or
Xextensions other than `.c', `.s' or `.o' are treated like files with
X`.o' extensions. Then all the files are linked with the default
Xstartup file START and the default libraries LIBS. The result is run
Xthru relmod to produce the executable image. The default name of the
Xexecutable image is NAME.
X
XThe default actions of Cc may be modified by specifying one or more of
Xthe following options that are interpreted by Cc.
X
X-c		Compile the file only. Don't run linker or relmod.
X		If the file name has a `.s' extension, then run the
X		assembler only. If the file name has a `.c' extension
X		then run the C compiler and assembler. If the file
X		name has any other extension, or no extension, ignore it.
X
X-w		Supress warnings from C compiler.
X
X-e		Run the macro preprocessor only, sending the result to stdout.
X
X-p		If present, specifies that the file and line number information
X		that is normally included in the preprocessed output is to
X		be omitted.
X
X-dname=def
X-dname		Define the name to the macro preprocessor, as if by
X		`#define'. If no defintion is given, the name is defined
X		as `1'. *Warning* the preprocessor converts `name' and
X		`def' to uppercase.
X
X-i d:		Allows using a different drive for the files in a
X		`#include <file.h>' statement. *Warning* Files in an
X		include statement within double quotes are unaffected by
X		this option.
X
X-s		Compile the `.c' files and leave the output assembler
X		files in corresponding files with `.s' suffixes. File
X		names with extensions other than `.s' are ignored. The
X		assembly, linker and relmod stages are not run.
X
X-f d:		Specifies the drive the assembler is to use for temporary
X		files.
X
X-llib		Use the library `lib' in addition to the default libraries
X		LIBS. Multiple -l options may be used.
X
X-o name		Name the output file name instead of the default NAME.
X		If name has no file name extention specified,
X		`.prg' is used. 
X
X-n		Show what actions will be performed if Cc were to be
X		run. No execution is performed (Like "make -n" ).
X
X
XNOTES:
X
XAll the options that take an additional arguement, allow an optional
Xblank to be specified between the option and the arguement.
X
XDEFAULTS:
X
XThe following are defaults compiled into Cc. One or more of the
Xdefaults may be changed, by editing and re-compiling cc.c.
X
XSymbol		Value	    Meaning
XSILENT		Defined	    Echo command to console before executing.
X		Undefined   Work Silently.
X
XDEBUG		Defined	    Echo command to console, but do not
X			    execute command (like -n option).
X
XWAIT		Defined     Wait for RETURN to be hit at the console
X			    before exiting Cc. Typically used when Cc
X			    is run from the desktop.
X		Undefined   Do not wait before exiting Cc.
X
XLINKW		Defined     Wait for disk change between compile and
X			    link. Typically defined when using single
X			    sided drives where the C compiler and
X			    assembler are on one disk, and the linker
X			    and relmod are on a separate disk. 
X		Undefined   Do not wait between compile or assembly
X			    and linking statges.
X
XDEF_DRIVE	"a:"  	    Default drive on which the Ccompiler,
X			    Assembler, linker, relmod and the
X			    libraries reside.
X
X
XPRE_PROC	"cp68.prg"  Name of the Macro Preprocessor.
X
XPRE_FLAGS	""	    Default Preprocessor flags. String must
X			    end in a blank if it is not NULL.
X
XPASS1		"c068.prg"  Name of Pass 1 of the C compiler.
X
XPASS1_FLAGS	" -f"	    Default flags to Pass 1. Note the blank
X			    before -f.
X
XPASS2		"c168.prg"  Name of Pass 2 of the C compiler.
X
XPASS2_FLAGS	""	    Default flags to Oass 2. Must begin with
X			    blank if not NULL.
X
XASM		"as68.prg"  Name of the assembler.
X
XASM_FLAGS	"-l -u -s a: " Default flags to the assembler. Must end
X			       in an blank.
X
XLINK		"link68.prg" Name of the Linker.
X
XLINK_FLAGS	"u"	     Default flags to the Linker. The list of
X			     flags is comma separated.
X
XRELMOD		"relmod.prg" Name  of the Relocater.
X
XRELMOD_FLAGS	""	     Default flags to the relocator.
X
XSTART		"gemstart"   Default startup file.
X
XLIBS		"gemlib"     List of libraries linked by default
X			     (comma separated).
X
XNAME		"a.prg"	     Name of output if '-o name' is not specified.
X
XKNAME		"a"	     NAME without the extension.
X
XNAME_EXT 	".prg"	     The extension to use if a '-o name' was
X			     specified but `name' did not have an extension.
X
XCOMPILING CC
X
XSources required: cc.c, getopt.c and syserr.c.
XInclude files:    osbind.h
X
XCc may be linked as follows (assuming compiler etc on drive a:)
X a:link68.prg [u] cc.68k=a:gemstart,cc.o,getopt.o,syserr.o,a:osbind.o,a:gemlib
X
Xor Cc could be used as follows (assuming compiler etc on drive a:)
X    cc -o cc -i a: -f d: cc.c getopt.c syserr.c a:osbind.o
X
XA word about gemstart:
X	Gemstart as supplied by Atari does not have enough stack and
Xheap space for anything other than trivial programs. Edit gemstart.s
Xand change the constant $500, to a value such as $4000, that will give
XCc about 16K of stack+heap space. Then reassemble gemstart before
Xlinking Cc. Cc will not work if linked with gems.o.
SHAR_EOF
if test 5567 -ne "`wc -c 'cc.doc'`"
then
	echo shar: error transmitting "'cc.doc'" '(should have been 5567 characters)'
fi
echo shar: extracting "'cc.c'" '(20547 characters)'
if test -f 'cc.c'
then
	echo shar: over-writing existing file "'cc.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'cc.c'
X/*
X * cc - Compile C programs
X * 
X * 	cc [options] ... file ...
X * 
X * Cc runs the various passes of the C compiler, followed by the assembler
X * and the linker and relmod to produce an executable image.
X * 
X * Cc accepts various types of `file' arguements. Files with a `.c'
X * extension are compiled and assembled to produce object files with the
X * `.o' extension. Files with `.s' extensions are assembled to produce
X * object files with `.o' extensions. File with `.o' extensions are
X * included in the list of files to be linked, in the position in which
X * they occur in the list of files. File names with no extension, or
X * extensions other than `.c', `.s' or `.o' are treated like files with
X * `.o' extensions. Then all the files are linked with the default
X * startup file START and the default libraries LIBS. The result is run
X * thru relmod to produce the executable image. The default name of the
X * executable image is NAME.
X * 
X * The default actions of Cc may be modified by specifying one or more of
X * the following options that are interpreted by Cc.
X * 
X * -c		Compile the file only. Don't run linker or relmod.
X * 		If the file name has a `.s' extension, then run the
X * 		assembler only. If the file name has a `.c' extension
X * 		then run the C compiler and assembler. If the file
X * 		name has any other extension, or no extension, ignore it.
X * 
X * -w		Supress warnings from C compiler.
X * 
X * -e		Run the macro preprocessor only, sending the result to stdout.
X * 
X * -p		If present, specifies that the file and line number information
X * 		that is normally included in the preprocessed output is to
X * 		be omitted.
X * 
X * -dname=def
X * -dname	Define the name to the macro preprocessor, as if by
X * 		`#define'. If no defintion is given, the name is defined
X * 		as `1'. *Warning* the preprocessor converts `name' and
X * 		`def' to uppercase.
X * 
X * -i d:	Allows using a different drive for the files in a
X * 		`#include <file.h>' statement. *Warning* Files in an
X * 		include statement within double quotes are unaffected by
X * 		this option.
X * 
X * -s		Compile the `.c' files and leave the output assembler
X * 		files in corresponding files with `.s' suffixes. File
X * 		names with extensions other than `.s' are ignored. The
X * 		assembly, linker and relmod stages not run.
X * 
X * -f d:	Specifies the drive the assembler is to use for temporary
X * 		files.
X * 
X * -llib	Use the library `lib' in addition to the default libraries
X * 		LIBS. Multiple -l options may be used.
X * 
X * -o name	Name the output file name instead of the default NAME.
X * 		If name has no file name extention is specified,
X * 		`.prg' is used. 
X * 
X * -n		Show what actions will be performed if Cc were to be
X * 		run. No execution is performed (Like "make -n" ).
X * 
X * 
X * NOTES:
X * 
X * All the options that take an additional arguement, allow an optional
X * blank to be specified between the option and the arguement.
X * 
X * DEFAULTS:
X * 
X * The following are defaults compiled into Cc. One or more of the
X * defaults may be changed, by editing and re-compiling cc.c.
X * 
X * Symbol		Value	    Meaning
X * SILENT		Defined	    Echo command to console before executing.
X * 			Undefined   Work Silently.
X * 
X * DEBUG		Defined	    Echo command to console, but do not
X * 				    execute command (like -n option).
X * 
X * WAIT			Defined     Wait for RETURN to be hit at the console
X * 				    before exiting Cc. Typically used when Cc
X * 				    is run from the desktop.
X * 				    Undefined   Do not wait before exiting Cc.
X * 
X * LINKW		Defined     Wait for disk change between compile and
X * 				    link. Typically defined when using single
X * 				    sided drives where the C compiler and
X * 				    assemblet are on one disk, and the linker
X * 				    and relmod are on a separate disk. 
X * 			Undefined   Do not wait between compile or assembly
X * 				    and linking statges.
X * 
X * DEF_DRIVE		"a:"  	    Default drive on which the Ccompiler,
X * 				    Assembler, linker, relmod and the
X * 				    libraries reside.
X * 
X * 
X * PRE_PROC		"cp68.prg"  Name of the Macro Preprocessor.
X * 
X * PRE_FLAGS		""	    Default Preprocessor flags. String must
X * 				    end in a blank if it is not NULL.
X * 
X * PASS1		"c068.prg"  Name of Pass 1 of the C compiler.
X * 
X * PASS1_FLAGS		" -f"	    Default flags to Pass 1. Note the blank
X * 				    before -f.
X * 
X * PASS2		"c168.prg"  Name of Pass 2 of the C compiler.
X * 
X * PASS2_FLAGS		""	    Defalt flags to Oass 2. Must begin with
X * 				    blank if not NULL.
X * 
X * ASM			"as68.prg"  Name of the assembler.
X * 
X * ASM_FLAGS		"-l -u -s a: " Default flags to the assembler. Must end
X * 				       in an blank.
X * 
X * LINK			"link68.prg" Name of the Linker.
X * 
X * LINK_FLAGS		"u"	     Default flags to the Linker. The list of
X * 				     flags is comma separated.
X * 
X * RELMOD		"relmod.prg" Name  of the Relocater.
X * 
X * RELMOD_FLAGS		""	     Default flags to the relocator.
X * 
X * START		"gemstart"   Default startup file.
X * 
X * LIBS			"gemlib"     List of libraries linked by default
X * 				     (comma separated).
X * 
X * NAME			"a.prg"	     Name of output if '-o name' is not specified.
X * 
X * KNAME		"a"	     NAME without the extension.
X * 
X * NAME_EXT 		".prg"	     The extension to use if a '-o name' was
X * 				     specified but `name' did not have
X *				     an extension.
X * 
X * COMPILING CC
X * 
X * Sources required: cc.c, getopt.c and syserr.c.
X * Include files:    osbind.h
X * 
X * Cc may be linked as follows (assuming compiler etc on drive a:)
X * a:link68.prg [u] cc.68k=a:gemstart,cc.o,getopt.o,syserr.o,a:osbind.o,a:gemlib
X * 
X * or Cc could be used as follows (assuming compiler etc on drive a:)
X *     cc -o cc -i a: -f d: cc.c getopt.c syserr.c a:osbind.o
X * 
X * A word about gemstart:
X * 	Gemstart as supplied by Atari does not have enough stack and
X * heap space for anything other than trivial programs. Edit gemstart.s
X * the constant $500, to a value such as $4000 that will give Cc about
X * 16K of stack+heap space. Then reassemble gemstart before linking Cc.
X * Note that Cc will not run if linked with gems.o.
X *
X */
X
X#include <osbind.h>
X
X	/* general definitions */
X#define EOF		((int) -1)
X#define TRUE		('\001')
X#define FALSE		('\0')
X#define NULL		(0)
X#define VOID		/* */
X#define CRLF		"\015\012"
X
X/* #define SILENT	1 */ /* Show command before executing if defined     */
X/* #define	DEBUG	1 */ /* While Debugging				     */
X/* #define WAIT		1 */ /* define if wait for ret at end of cc          */
X			     /* Typically for use from Desktop		     */
X#define LINKW		1    /* define if wait for disk change between	     */
X			     /* compile and link			     */
X#define DEF_DRIVE	"a:" /* Default drive on which the Ccompiler is found*/
X			     /* drive on which the assembler is found	     */
X			     /* drive on which the linker    is found	     */
X			     /* drive on which Relmod        is found	     */
X			     /* drive on which the libraries are found	     */
X
X	/* default passes and flags */
X#define PRE_PROC	"cp68.prg"
X#define PRE_FLAGS	""	/* Must end with a blank if any flags */
X#define PASS1		"c068.prg"
X#define PASS1_FLAGS	" -f"	/* Note the blank before -f */
X#define PASS2		"c168.prg"
X#define PASS2_FLAGS	""	/* Must begin with blank if any flags */
X#define ASM		"as68.prg"
X#define ASM_FLAGS	"-l -u -s a: " /* Must end in an blank */
X#define LINK		"link68.prg"
X#define LINK_FLAGS	"u"
X#define RELMOD		"relmod.prg"
X#define RELMOD_FLAGS	""
X
X	/* default names and libraries */
X#define START		"gemstart"
X#define LIBS		"gemlib"
X#define KNAME		"a"
X#define NAME		"a.prg"
X#define NAME_EXT 	".prg"
X 
Xtypedef char BOOLEAN;
X
X/* Flags */
XBOOLEAN c_flag = FALSE;
XBOOLEAN s_flag = FALSE;
XBOOLEAN e_flag = FALSE;
XBOOLEAN p_flag = FALSE;
X
X#ifdef DEBUG
XBOOLEAN n_flag = TRUE;
XBOOLEAN do_flag = FALSE;
X#else
X#ifndef SILENT
XBOOLEAN n_flag = TRUE;
X#else
XBOOLEAN n_flag = FALSE;
X#endif
XBOOLEAN do_flag = TRUE;
X#endif
X
X
X	/* globals */
Xlong status      = 0L;			/* Status accumulator		     */
Xchar *pre_flags  = (char *)NULL;	/* List of flags to the preprocessor */
Xchar *pass1_flags = (char *)NULL;	/* List of flags to the pass1 C comp */
Xchar *asm_flags  = (char *)NULL;	/* List of flags to the assembler    */
Xchar *output	 = (char *)NULL;	/* Name of executable output	     */
Xchar *k_output	 = (char *)NULL;	/* Name of .68K intermed. file	     */
Xchar *link_files = (char *)NULL;	/* List of .o files to be linked     */
Xchar *libes	 = (char *)NULL;	/* List of libraries to use	     */
Xchar cmd[258];				/* cmd[0] = len of command tail
X					   cmd[1..] = command tail
X					   max len 256. + a byte for NULL
X					 */
Xchar *cmd_ptr    = &cmd[1];
Xchar *ret_msg     = "Hit RETURN to continue ......"; /* General Message */
X	/* external functions */
Xextern VOID sys_error();
X
X
X
X/*
X * Initialize everything
X */
XVOID init()
X{
X	extern char *expand();
X
X	pre_flags  = expand(pre_flags,PRE_FLAGS);
X	pass1_flags  = expand(pass1_flags,PASS1_FLAGS);
X	asm_flags  = expand(asm_flags,ASM_FLAGS);
X
X	output	   = expand(output,NAME);
X	k_output   = expand(k_output,KNAME);
X	libes	   = expand(libes,DEF_DRIVE);
X	libes	   = expand(libes,LIBS);
X}
X
X
X/* 
X * Add to string `string' the additional string `add', reallocating storage.
X * Returns pointer to resultant string. Exits after message on error.
X */
Xchar *expand(string,add)
Xregister char *string;
Xregister char *add;
X{
X	extern char *malloc(), *realloc(), *strcpy(), *strcat();
X	extern int strlen();
X
X	if(add == (char *)NULL)
X		/* We have nothing to do */
X		return(string);
X
X	if(string == (char *)NULL)
X	{
X		/* just alloc storage, copy and return */
X		if((string = malloc(strlen(add)+1)) == (char *)NULL)
X			/* out of mem */
X#ifdef DEBUG
X			error(0,"expand");
X#else
X			error(0);
X#endif
X		strcpy(string,add);
X		return(string);
X	}
X	else
X	{
X		register int tlen;
X
X		tlen = strlen(string) + strlen(add) + 1;
X		if(tlen > 256)
X			/* we can't do it */
X#ifdef DEBUG
X			error(1,"expand");
X#else
X			error(1);
X#endif
X		if((string = realloc(string,tlen)) == (char *)NULL)
X			/* out of mem */
X#ifdef DEBUG
X			error(0,"expand");
X#else
X			error(0);
X#endif
X
X		strcat(string,add);
X
X		return(string);
X	}
X}
X
X
X#define	DOT_C	0
X#define DOT_O	1
X#define DOT_S	2
X#define DOT_X   3	/* Dont care, treat as .o */
X
X/*
X * Ext_type - the extention type of a file name
X */
Xint ext_type(filename)
Xchar *filename;
X{
X	extern char *rindex();
X	extern int strlen();
X	register char *p;
X
X	if((p = rindex(filename,'.')) == (char *)NULL)
X		/* no extention */
X		return(DOT_X);
X
X	p++;
X	if(strlen(p) > 1)
X		/* something more than .X */
X		return(DOT_X);
X
X	switch(*p)
X	{
X		case 'c':
X		case 'C':
X			return(DOT_C);
X
X		case 's':
X		case 'S':
X			return(DOT_S);
X
X		case 'o':
X		case 'O':
X			return(DOT_O);
X
X		default:
X			return(DOT_X);
X	}
X}
X
Xchar *basename(file)	/* Return the base name of a file name
X			   ie. everything but the .ext */
Xchar *file;
X{
X	register char *b, *end;
X	register int len;
X	extern char *malloc(), *rindex(), *strncpy();
X	extern int strlen();
X
X	if((end = rindex(file,'.')) == (char *)NULL)
X		len = strlen(file);
X	else
X		len = (int) ( (long)end - (long)file );
X
X	if((b = malloc(len+1)) == (char *)NULL)
X		/* out of memory */
X#ifdef DEBUG
X			error(0,"basename");
X#else
X			error(0);
X#endif
X
X	strncpy(b,file,len);
X	b[len] = '\0';
X
X	return(b);
X}
X
X
XVOID usage()
X{
X  Cconws("Usage: cc [-c][-e][-w][-p][-s][-i d:][-dsymbol[=name]][-f d:]\r\n");
X  Cconws("          [-l library][-o name[.ext]] files .....\r\n");
X#ifdef WAIT
X	wait_msg(ret_msg);
X#endif
X	exit(1);
X}
X
X		
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	register int c;
X	register char *file, *base;
X	extern int optind, getopt(), ext_type();
X	extern char *optarg, *expand(), *rindex(), *basename();
X
X	if(argc < 2)
X		/* nothing to do */
X		exit(0);
X
X	init();
X
X    while ((c = getopt(argc,argv, "CEPSWNcepswnD:I:F:L:O:d:i:f:l:o:")) != EOF)
X	switch (c)
X	{
X	    case 'n':
X	    case 'N':
X		do_flag = FALSE;
X		n_flag  = TRUE;
X
X		break;
X
X	    case 'C':
X	    case 'c':
X		/* compile only (compile and assemble) */
X		 c_flag = TRUE;
X		 break;
X
X	    case 'e':
X	    case 'E':
X		/* pre processor only, sending output to stdout */
X		if(e_flag == TRUE)
X			break; /* Already Specified */
X
X		e_flag = TRUE;
X		pre_flags = expand(pre_flags, "-e ");
X		break;
X
X	    case 's':
X	    case 'S':
X		/* produce .s file (compiler only) */
X		 s_flag = TRUE;
X		 break;
X
X	    case 'p':
X	    case 'P':
X		/* dont include file names and line #'s */
X		if(p_flag == TRUE)
X			break;	/* Already specified */
X
X		p_flag = TRUE;
X		pre_flags = expand(pre_flags, "-p ");
X		break;
X
X	    case 'd':
X	    case 'D':
X		pre_flags = expand(pre_flags, "-d");
X		pre_flags = expand(pre_flags, optarg);
X		pre_flags = expand(pre_flags, " ");
X
X		break;
X
X
X	    case 'w':
X	    case 'W':
X		pass1_flags = expand(pass1_flags, " -w");
X
X		break;
X
X
X	    case 'i':
X	    case 'I':
X		pre_flags = expand(pre_flags, "-i ");
X		pre_flags = expand(pre_flags, optarg);
X		if(rindex(optarg, ':') == (char *)NULL)
X			/* Ok he forgot, we will add it for him */
X			pre_flags = expand(pre_flags, ":");
X
X		pre_flags = expand(pre_flags, " ");
X
X		break;
X		
X	    case 'l':
X	    case 'L':
X		libes = expand(libes, ",");
X		libes = expand(libes, optarg);
X
X		break;
X
X	    case 'f':
X	    case 'F':
X		asm_flags = expand(asm_flags, "-f ");
X		asm_flags = expand(asm_flags, optarg);
X		if(rindex(optarg, ':') == (char *)NULL)
X			/* Ok he forgot, we will add it for him */
X			asm_flags = expand(asm_flags, ":");
X
X		asm_flags = expand(asm_flags, " ");
X
X		break;
X		
X	    case 'o':
X	    case 'O':
X		{
X			register char *p;
X			/* name of output file */
X
X			free(k_output);
X			free(output);
X			k_output = (char *)NULL;
X			output   = (char *)NULL;
X			p = basename(optarg);
X			k_output = expand(k_output,p);
X			free(p);
X			output   = expand(output,optarg);
X			if(rindex(optarg,'.') == (char *)NULL)
X				/* No extention */
X				output = expand(output,NAME_EXT);
X		}
X
X		break;
X
X	    case '?':
X	    default:
X		 usage();
X
X		 break;
X	} /* Switch and While */
X
X	if((e_flag == FALSE) && (s_flag == FALSE) && (c_flag == FALSE))
X	{
X		link_files = expand(link_files,DEF_DRIVE);
X		link_files = expand(link_files,START);
X	}
X
X	if(optind >= argc)
X	{
X		/* Nothing to do */
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(0);
X	}
X
X	for (; optind < argc; optind++)
X	{
X		file = argv[optind];
X		base = basename(file);
X		switch(ext_type(file))
X		{
X		    case DOT_C:
X			/* A .c file */
X			if(e_flag == TRUE)
X				pre_process(file,base);
X			else
X			{
X				c_compile(file,base);
X				if(s_flag == FALSE)
X				    	/* assemble and remove .s file */
X					assemble(base, TRUE);
X			}
X
X			break;
X
X		    case DOT_S:
X			if(s_flag == TRUE)
X				break;
X
X			/* assemble, do not remove .s file */
X			assemble(base,FALSE);
X
X			break;
X
X		    case DOT_X:
X			if(e_flag == TRUE)
X				pre_process(file,base);
X
X			break;
X
X		    case DOT_O:
X		    default:
X
X			break;
X
X		} /* switch */
X
X		if((s_flag == FALSE) && (e_flag == FALSE) && (c_flag == FALSE))
X		{
X			link_files = expand(link_files,",");
X			link_files = expand(link_files,base);
X			link_files = expand(link_files,".o");
X		}
X
X		free(base);
X	} /* for */
X
X	/* Free up memory not needed */
X	if(pre_flags != (char *)NULL)
X		free(pre_flags);
X	if(asm_flags != (char *)NULL)
X		free(asm_flags);
X
X	if((s_flag == FALSE) && (e_flag == FALSE) && (c_flag == FALSE))
X	{
X		link_files = expand(link_files,",");
X		link_files = expand(link_files,libes);
X		if(libes != (char *)NULL)
X			free(libes);
X
X#ifdef LINKW
X		wait_msg("Insert Linker Disk and hit RETURN .....");
X#endif
X
X		rel_link();
X	}
X
X#ifdef WAIT
X	wait_msg(ret_msg);
X#endif
X	exit((status == 0L)? 0 : 1);	/* Cumulative status for all we 
X					   have (not)done */
X
X}
X
X
XVOID pre_process(file,base)	/* Run the C preprocessor */
Xchar *file;
Xchar *base;
X{
X	extern long do_exec();
X	extern char *expand(), *strcpy(), *strcat();
X	register char *command;
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,PRE_PROC);
X
X	strcpy(cmd_ptr,(pre_flags != (char *)NULL)? pre_flags : "");
X	strcat(cmd_ptr,file);
X	strcat(cmd_ptr," ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".i");
X	if((status = do_exec(command,cmd)) != 0L)
X	{
X		rm_if_exist(base,".i");
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X	
X	if(e_flag == TRUE)
X		rm_if_exist(base,".i");
X
X	free(command);
X}
X
XVOID c_compile(file,base)	/* Run the C Compiler */
Xchar *file;
Xchar *base;
X{
X	extern long do_exec();
X	extern char *expand(), *strcpy(), *strcat();
X	register char *command;
X
X	pre_process(file,base);
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,PASS1);
X
X	strcpy(cmd_ptr,base);
X	strcat(cmd_ptr,".i ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".1 ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".2 ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".3");
X	strcat(cmd_ptr,pass1_flags);
X	if((status = do_exec(command,cmd)) != 0L)
X	{
X		rm_if_exist(base,".i");
X		rm_if_exist(base,".1");
X		rm_if_exist(base,".2");
X		rm_if_exist(base,".3");
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X
X	rm_if_exist(base,".i");
X	free(command);
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,PASS2);
X
X	strcpy(cmd_ptr,base);
X	strcat(cmd_ptr,".1 ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".2 ");
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".s");
X	strcat(cmd_ptr,PASS2_FLAGS);
X
X	status = do_exec(command,cmd);
X	rm_if_exist(base,".1");
X	rm_if_exist(base,".2");
X	if(status != 0L)
X	{
X		rm_if_exist(base,".s");
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X
X	free(command);
X}
X
X
XVOID rel_link()	/* Run the linker and relmod */
X{
X	extern long do_exec();
X	extern char *expand(), *strcpy(), *strcat();
X	register char *command;
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,LINK);
X
X	strcpy(cmd_ptr,"[");
X	strcat(cmd_ptr,LINK_FLAGS);
X	strcat(cmd_ptr,"] ");
X	strcat(cmd_ptr,k_output);
X	strcat(cmd_ptr,".68k");
X	strcat(cmd_ptr,"=");
X	strcat(cmd_ptr,link_files);
X	free(link_files);
X	if((status = do_exec(command,cmd)) != 0L)
X	{
X		rm_if_exist(k_output,".68k");
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X
X	free(command);
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,RELMOD);
X
X	strcpy(cmd_ptr,RELMOD_FLAGS);
X	strcat(cmd_ptr,k_output);
X	status = do_exec(command,cmd);
X	rm_if_exist(k_output,".68k");
X	if(status != 0L)
X	{
X		rm_if_exist(output,"");
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X
X	free(command);
X}
X
XVOID assemble(base,del_s)	/* Assemble a file, delete .s if del_s TRUE */
Xchar *base;
XBOOLEAN del_s;
X{
X	extern long do_exec();
X	extern char *expand(), *strcpy(), *strcat();
X	register char *command;
X
X	command = expand((char *)NULL,DEF_DRIVE);
X	command = expand(command,ASM);
X
X	strcpy(cmd_ptr,asm_flags);
X	strcat(cmd_ptr,base);
X	strcat(cmd_ptr,".s");
X
X	status = do_exec(command,cmd);
X	if(del_s == TRUE)
X		rm_if_exist(base,".s");
X
X	if(status != 0L)
X	{
X		sys_error(status);
X#ifdef WAIT
X		wait_msg(ret_msg);
X#endif
X		exit(1);
X	}
X
X	free(command);
X}
X
XVOID rm_if_exist(file,ext)	/* remove a file is it exists */
Xchar *file;
Xchar *ext;
X{
X	register char *name;
X	extern char *malloc(), *strcpy(), *strcat();
X	extern int strlen();
X
X	if((name = malloc(strlen(name) + strlen(ext) + 1)) == (char *)NULL)
X	{
X		/* Out of mem */
X#ifdef DEBUG
X			error(0,"rm_if_exist");
X#else
X			error(0);
X#endif
X	}
X
X	strcpy(name,file);
X	strcat(name,ext);
X
X	if(n_flag == TRUE)
X	{
X		Cconws("Deleting ");
X		Cconws(name);
X		Cconws(CRLF);
X	}
X
X#ifndef DEBUG
X	Fdelete(name);	/* disregard error */
X#endif
X	free(name);
X}
X
X
Xstatic char *my_err[] = {
X	"Out of Memory",
X	"Cannot handle strings longer than 256 internally"
X};
X
X
X#ifdef DEBUG
XVOID error(n,func)
Xint n;
Xchar *func;
X#else
XVOID error(n)
Xint n;
X#endif
X{
X	Cconws("CC: ");
X	Cconws(my_err[n]);
X#ifdef DEBUG
X	Cconws(" in Function ");
X	Cconws(func);
X#endif
X	Cconws(CRLF);
X
X#ifdef WAIT
X	wait_msg(ret_msg);
X#endif
X	exit(1);
X}
X
X
Xlong do_exec(command,tail) /* execute a command */
Xchar *command;
Xchar *tail;
X{
X	register unsigned int len;
X	register char *p;
X	extern int strlen();
X
X	/* the format of the command tail is
X         * tail[0] = len of tail.
X	 * tail[1..len] = <string>
X	 * tail[len+1] = '\0'
X	 */
X
X	p = tail + (long)sizeof(char);
X	if((len = strlen(p)) > 255)
X	{
X#ifdef DEBUG
X		error(1,"do_exec");
X#else
X		error(1);
X#endif
X	}
X
X	*tail = (char)len;
X
X	if(n_flag == TRUE)
X	{
X		Cconws(command);
X		Cconws(" ");
X		Cconws(p);
X		Cconws(CRLF);
X	}
X
X
X	if(do_flag == TRUE)
X		return(Pexec(0,command,tail,(char *)NULL));
X	else
X		return(0L);
X}
X
X
XVOID wait_msg(msg)	/* Wait for RETURN after displaying message */
Xchar *msg;
X{
X	register int c;
X
X	Cconws(msg);
X	while((c = Cnecin()) != '\r' && (c != '\n'));
X	Cconws(CRLF);			/* Echo CRLF */
X
X}
SHAR_EOF
if test 20547 -ne "`wc -c 'cc.c'`"
then
	echo shar: error transmitting "'cc.c'" '(should have been 20547 characters)'
fi
echo shar: extracting "'getopt.c'" '(1602 characters)'
if test -f 'getopt.c'
then
	echo shar: over-writing existing file "'getopt.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'getopt.c'
X/* got this off net.sources */
X/* see getopt.doc for origonal author */
X
X/* Ported to the 520ST - bammi@case */
X
X#include <osbind.h>
X
X#define CRLF	"\015\012"
X
X#define EOF	((int)-1)
X#define NULL	(0)
X/*
X * get option letter from argument vector
X */
X
Xint	opterr = 1,		/* useless, never set or used */
X	optind = 1,		/* index into parent argv vector */
X	optopt;			/* character checked for validity */
Xchar	*optarg;		/* argument associated with option */
X
X#define BADCH	(int)'?'
X#define EMSG	""
X#define tell(s)	Cconws((char *)*nargv);Cconws((char *)s); \
X		Cconout((int)optopt);Cconws(CRLF);return(BADCH);
X
Xint getopt(nargc,nargv,ostr)
Xint	nargc;
Xchar	**nargv,
X	*ostr;
X{
X	static char	*place = EMSG;	/* option letter processing */
X	register char	*oli;		/* option letter list index */
X	extern char	*index();
X
X	if(!*place) {			/* update scanning pointer */
X		if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
X		if (*place == '-') {	/* found "--" */
X			++optind;
X			return(EOF);
X		}
X	}				/* option letter okay? */
X	if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
X		if(!*place) ++optind;
X		tell(": illegal option -- ");
X	}
X	if (*++oli != ':') {		/* don't need argument */
X		optarg = (char *)NULL;
X		if (!*place) ++optind;
X	}
X	else {				/* need an argument */
X		if (*place) optarg = place;	/* no white space */
X		else if (nargc <= ++optind) {	/* no arg */
X			place = EMSG;
X			tell(": option requires an argument -- ");
X		}
X	 	else optarg = nargv[optind];	/* white space */
X		place = EMSG;
X		++optind;
X	}
X	return(optopt);			/* dump back option letter */
X}
SHAR_EOF
if test 1602 -ne "`wc -c 'getopt.c'`"
then
	echo shar: error transmitting "'getopt.c'" '(should have been 1602 characters)'
fi
echo shar: extracting "'syserr.c'" '(1842 characters)'
if test -f 'syserr.c'
then
	echo shar: over-writing existing file "'syserr.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'syserr.c'
X#include <osbind.h>
X
X#define CRLF	"\015\012"
X#define VOID	/* */
X#define NULL	(0)
X
Xstatic char *sy_err_list[] = {
X	/*   0L */	"OK, no error",
X	/*  -1L */	"basic, fundamental error",
X	/*  -2L */	"drive not ready",
X	/*  -3L */	"unknown command",
X	/*  -4L */	"CRC error",
X	/*  -5L */	"bad request",
X	/*  -6L */	"seek error",
X	/*  -7L */	"unknown media",
X	/*  -8L */	"sector not found",
X	/*  -9L */	"no paper",
X	/* -10L */	"write fault",
X	/* -11L */	"read fault",
X	/* -12L */	"general error",
X	/* -13L */	"write protect",
X	/* -14L */	"media change",
X	/* -15L */	"unknown device",
X	/* -16L */	"bad sectors on format",
X	/* -17L */	"insert other disk",
X
X/* BDOS level errors */
X
X	/* -32L */	"invalid function number",
X	/* -33L */	"file not found",
X	/* -34L */	"path not found",
X	/* -35L */	"too many open files (no handles left)",
X	/* -36L */	"access denied",
X	/* -37L */	"invalid handle",
X	/* -39L */	"insufficient memory",
X	/* -40L */	"invalid memory block address",
X	/* -46L */	"invalid drive was specified",
X	/* -49L */	"no more files",
X
X/* Atari's own inventions */
X
X	/* -64L */	"range error",
X	/* -65L */	"internal error",
X	/* -66L */	"invalid program load format",
X	/* -67L */	"setblock failure due to growth restrictions"
X};
X
Xstatic char *unknown = "Unknown System Error";
X
XVOID sys_error(n)
Xlong n;
X{
X	register char *p;
X
X	if(n > 0)
X		p = unknown;
X	else
X	{
X		n = -n;
X		if((n >= 0) && (n < 18))
X			p = sy_err_list[n];	/* 0 <= n < 18 */
X		else
X			if((n >=18) && (n < 32))
X				p = unknown;
X			else
X				if((n >= 32) && (n < 50))
X				    p = sy_err_list[n - 14]; /* 32 <= n < 50 */
X				else
X					if((n > 49) && (n < 64))
X						p = unknown;
X					else
X						if((n >= 64) && (n < 68))
X						  p = sy_err_list[n - 36];
X							/* 64 <= n < 68 */
X						else
X						  p = unknown;
X	} /* Phew ! */
X
X	Cconws("System Error: ");
X	Cconws(p);
X	Cconws(CRLF);
X
X}
SHAR_EOF
if test 1842 -ne "`wc -c 'syserr.c'`"
then
	echo shar: error transmitting "'syserr.c'" '(should have been 1842 characters)'
fi
#	End of shell archive
exit 0

-- 
					Jwahar R. Bammi
			       Usenet:  .....!decvax!cwruecmp!bammi
			        CSnet:  bammi@case
				 Arpa:  bammi%case@csnet-relay
			   CompuServe:  71515,155