/* cc compiler driver for Lattice C v5.0	*/
/* by Carlo Borreo				*/

#include "proto/exec.h"
#include "proto/dos.h"
#include "arpfunctions.h"
#include "libraries/dos.h"

#define MAXLEN	30
#define MAXDIM	(MAXLEN+10)
#define BUILD		buildname(s+2,nopath)
#define MYCAT3(A,B,C)	mycat( (A), mycat( (B), (C) ) )

#define check(F,S) { if ( !(F) ) error( S ) ; }

struct ArpBase *ArpBase;

int vflg=0, cflg=!0, oflg=0, gflg=0;

void	main( int argc, char *argv[] ) ;
void	myexec( char *com, char *args, char *fileres ) ;
int	exists( char *fn ) ;
void	clall( int n ) ;
char	*mycat( char *s1, char *s2 ) ;
void	complete( char *ftype, char *fname ) ;
void	error( char *msg ) ;
char	*buildname( char *s, char *nopath ) ;

void main( int argc, char *argv[] )
{
register int i;
char	*dotc, *quad=NULL, *obj=NULL, *fname=NULL, *nopath, *final=NULL,
	*lc1opt="-oQUAD: ", *lc2opt="-v ", *s, temp[256],
	*bopt="sc sd nd", *libs="LIB:lc.lib,LIB:Amiga.lib",*startup="LIB:c.o";

ArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L);
if (ArpBase==NULL) { Write(Output(),"No arp.library\n",15); Exit(20); }
for (i=1; i<argc; i++) {
    s=argv[i];
    if (s[0] != '-') {
	check(fname==NULL ,"Bad args");
	fname=s;
	if (s[strlen(s)-2]=='.')
	    switch(s[strlen(s)-1]) {
		case 'c': s[strlen(s)-2]='\0'; break;
		case 'o': cflg=0; break;
		}
	nopath=BaseName(fname);
	}
    else switch(s[1]) {
	case 'z': startup=s+2; break;		/* startup code		*/
	case 'B': bopt =s+2; break;		/* blink options	*/
	case ',': libs=mycat(libs,s+1);	break;	/* add libraries	*/
	case 'M': libs=s+2; break;		/* libraries modify	*/
	case 'e': final=BUILD; break;		/* executable file name	*/
	case 'o': if (s[2]) obj=mycat(BUILD,".o");
 		  lc2opt=MYCAT3(lc2opt,s," ");
		  oflg=!0; break;		/* no linking		*/
	case 'v': vflg=!0; break;		/* print commands	*/
	case 'O': gflg=!0; break;		/* call optimizer (GO)	*/

	case 'c': case 'i': case 'l':
	case 'n': case 'u': case 'x':
	case 'd': case 'b': case 'h':
					lc1opt=MYCAT3(lc1opt,s," "); break;
	case 'f': case 'm': case 'r':
	case 's': case 'y':
					lc2opt=MYCAT3(lc2opt,s," "); break;
	case 'a': lc2opt=mycat(lc2opt,"-c ");
	default : check(0, mycat("Unknown option: ",s));
	}
    }
if ( fname == NULL )
	{
	printf( "CC v2.00 compiled on " __DATE__","__TIME__"\n" ) ;
	printf( "Usage: CC [options] filename\n" ) ;
	printf( "-v\t\tVerbose mode, print commands to be executed\n" ) ;
	printf( "-z\t\tSpecify startup code\n" ) ;
	printf( "-c -i -l -n -u\n-x -d -b -h\tUse lc1 options ...\n" ) ;
	printf( "-f -m -r -s -y\tUse lc2 options ...\n" ) ;
	printf( "-a\t\tUse lc2 option -c\n" ) ;
	printf( "-O\t\tCall global optimizer GO\n" ) ;
	printf( "-B\t\tUse blink options ...\n" ) ;
	printf( "-o\t\tNo linking\n" ) ;
	printf( "-e\t\tSpecify executable name\n" ) ;
	printf( "-M\t\tModify libraries list\n" ) ;
	Exit( 1 ) ;
	}
check(fname, "No filename");
check(strlen(fname) < MAXLEN, "filename too long");
if (cflg) {
	if (final==NULL) final=fname;
	dotc=mycat (fname,".c");
	if (quad==NULL) quad=MYCAT3("QUAD:",nopath,".q");
	if (obj ==NULL) obj =MYCAT3("QUAD:",nopath,".o");
	check(exists(dotc),"source file not found");
	myexec("lc1",mycat(lc1opt,dotc),quad);
	if (gflg) myexec("go",quad,quad);
	myexec("lc2",mycat(lc2opt,quad),obj);
	if (oflg) complete("object",obj);
	}
sprintf(temp,"%s %s TO %s LIB %s %s",startup,obj,final,libs,bopt);
myexec("blink",temp,final);
check(DeleteFile(obj),"Can't delete obj");
complete("executable",final);
}

void myexec( char *com, char *args, char *fileres )
{
if (vflg) printf("---> %s %s\n",com,args);
SyncRun(com,args,NULL,NULL);
check(exists(fileres),"file not produced");
}

int exists( char *fn )
{
BPTR lock;

if ((lock=Lock(fn,ACCESS_READ))==0) return 0;
UnLock(lock);
return !0;
}

void clall( int n )
{
ArpExit(n,0);
}

char *mycat( char *s1, char *s2 )
{
char *s;

check(s=(char *)malloc(strlen(s1)+strlen(s2)+1),"mycat");
sprintf(s,"%s%s",s1,s2);
return s;
}

void complete( char *ftype, char *fname )
{
printf("*** OK, you now have %s file %s\n", ftype, fname);
clall(0);
}

void error( char *msg )
{
printf("CC: %s\n",msg);
clall(20);
}

char *buildname( char *s, char *nopath )
{
s += strlen(s)-1;
if ( *s==':' || *s=='/' )
	return mycat(s, nopath);
else
	return s;
}
