#ifndef lint
static char sccsid[] = "@(#)perf.c	1.5 (mg@ukc.ac.uk) 5/31/90";
#endif
#include <stdio.h>		/*						PERF.C		*/
#include <signal.h>		/*	Csound perf command	*/
#include "sysdep.h"

extern char *tmpnam();

struct argsstruct {
	char	*dcodes;
	char	*mcodes;
	char	*outfile;
	char	*orchname;
	char	*xfile;
	char	*scorename;
	int	perfi;
	int	perfn;
	int	perff;
	int	perfv;
	int	perft;
#ifdef ULAW
	int	perfu;
#endif
	int	orchP;
	int	scoreP;
	int	scorex;
	int	scores;
} args;

static  char	command[200], message[200];
static  char	*scoretmp;

main(argc,argv)
 int argc; char **argv;
{
    getinput(argc,argv);

    if(args.orchname != NULL && strcmp(args.orchname,".") != 0)
	checkfile(args.orchname);
    if(args.xfile != NULL)	
	checkfile(args.xfile);
    if(args.scorename != NULL)	
	checkfile(args.scorename);
    scoretmp = tmpnam(NULL, "perf");
    						/* SCORE PROCESSING:	*/
    fprintf(stderr,"score preprocessing:\n");

    if(args.scorename == NULL) {	 	/* using previous score.srt */
	systemcall("test -f score.srt","'score.srt' absent. Score name required");
	fprintf(stderr,"  using previous 'score.srt'\n");
    }
    else {					/*  or create new one	*/
	if(args.scoreP) {
	    sprintf(command,"/lib/cpp -P < %s > %s",args.scorename,scoretmp);
	    systemcall(command,"C pre-processor failed on score");
	    args.scorename = scoretmp;
        }
	if(args.scores) {
	    sprintf(command,"scot %s",args.scorename);
	    systemcall(command,"SCOT failed");
	    args.scorename = "score";
        }
	sprintf(command,"scsort < %s > score.srt", args.scorename);
	systemcall(command,"score sort failed");
    }
    if(args.scorex) {				     /* now extract or copy */
	sprintf(command,"extract %s < score.srt > %s", args.xfile, scoretmp);
	systemcall(command,"score extract failed");
    }
    else {					    /*	   score.srt to tmp */
	sprintf(command,"cp score.srt %s", scoretmp);
	sprintf(message,"cp score.srt to %s failed", scoretmp);
	systemcall(command,message);
    }

    						/* ORCHESTRA PROCESSING:   */
    fprintf(stderr,"orch preprocessing:\n");
    						/* using previous orch.orc */
    if(args.orchname == NULL || strcmp(args.orchname,".") == 0) {
	systemcall("test -f orch.orc","'orch.orc' absent. New orchname required");
	fprintf(stderr,"  using previous 'orch.orc'\n");
    }
    else {					/* else use given orchestra */
	if(args.orchP) {
	    sprintf(command,"/lib/cpp -P < %s > orch.orc", args.orchname);
	    systemcall(command,"C pre-processing of orch failed");
	}
	else {
	    sprintf(command,"cp %s orch.orc", args.orchname);
	    systemcall(command,"copy to orch.orc failed");
	}
    }

    sprintf(command,"csound");
    catorchscor();                                  /* build command   */
    fprintf(stderr,"%s\n",command);
    systemcall(command,"perf failed during `orch'"); /*  & run now  */

    cleanup();
    return(0);
}


catorchscor()			/* build command from orch, score & flags */
{
	if(args.perfi || args.perfn || args.perff || args.perfv || args.perft
#ifdef ULAW
	|| args.perfu
#endif
	){
		strcat(command," -");
	    	if(args.perfi) strcat(command,"i");
		if(args.perfn) strcat(command,"n");
	    	if(args.perff) strcat(command,"f");
	        if(args.perfv) strcat(command,"v");
	        if(args.perft) strcat(command,"t");
#ifdef ULAW
	        if(args.perfu) strcat(command,"u");
#endif
	}
	if(args.dcodes != NULL) {
		strcat(command," -d");
		strcat(command,args.dcodes);
	}
	if(args.mcodes != NULL) {
		strcat(command," -m");
		strcat(command,args.mcodes);
	}
	if(args.outfile != NULL) {
		strcat(command," -N");
		strcat(command,args.outfile);
	}
	strcat(command," orch.orc <");
	strcat(command,scoretmp);
}

systemcall(call,errmsg)
 char *call, *errmsg;
{
	if(system(call) != 0) {			/* if abnormal ending,	*/
	    signal(SIGINT,SIG_IGN);		/*	hold off sigs	*/
	    fprintf(stderr,"Perf error: %s\n",errmsg);
	    cleanup();
	    exit(1);				/*	clean & exit	*/
	}
}

cleanup() {
	unlink(scoretmp);
}	

checkfile(filename)
 char *filename;
{
	sprintf(command,"test -f %s -a -s %s",filename,filename);
	sprintf(message,"this perf needs file:  %s",filename);
	systemcall(command, message);
}

getinput(argc,argv)
 int argc; char *argv[];
{
register int	i;

    for (i = 1; i < argc; ++i ) {
	char c, *s;
	s = argv[i];
	if(args.orchname == NULL) {
	    if(*s++ == '-') {
		while ((c = *s++) != '\0') {
		    switch(c) {
		    case 'i': args.perfi++; break;
		    case 'n': args.perfn++; break;
		    case 'f': args.perff++; break;
		    case 'v': args.perfv++; break;
		    case 't': args.perft++; break;
#ifdef ULAW
		    case 'u': args.perfu++; break;
#endif
		    case 'd': if (*s == NULL)	   /* dcodes follow directly */
		    		s = argv[++i];		/* or in next arg    */
			      args.dcodes = s;
		    	      while (*++s); break;
		    case 'm': if (*s == NULL)	   /* mcodes follow directly */
		    		s = argv[++i];		/* or in next arg    */
			      args.mcodes = s;
		    	      while (*++s); break;
		    case 'N': if (*s == NULL)	  /* sfname follows directly */
		    		s = argv[++i];		/* or in next arg    */
			      args.outfile = s;
		    	      while (*++s); break;
		    case 'P': args.orchP++; break;
		    case 'h': fprintf(stderr,
		    "Usage: perf [-orchflags] [orch] [-scoreflags] [score]\n");
		    default:
		    fprintf(stderr, "Legal flags are:\n");
fprintf(stderr,"-i\ti-time only orch run\n");
fprintf(stderr,"-n\tno sound onto disk\n");
fprintf(stderr,"-f\tfloat sound samples\n");
#ifdef ULAW
fprintf(stderr,"-u\tulaw-encoded sound output\n");
#endif
fprintf(stderr,"-v\tverbose mode\n");
fprintf(stderr,"-t\tsupress ftable display\n");
fprintf(stderr,"-d..\tdisplay option: 0=nodisplay, 1=simple ascii, 2=Xwindow slow,\n\t\t3=Xwindow rapid, 4=high-resolution display\n");
fprintf(stderr,"-m..\ttty message level. Sum of: 1=note amps, 2=out-of-range msg, 4=warnings\n");
fprintf(stderr,"-N fnam\tsoundfile output name\n");
fprintf(stderr,"-P\tC preprocess orch or score\n");
fprintf(stderr,"-x fnam\textract from score.srt using extract file 'fnam'\n");
fprintf(stderr,"-s\tscore is in scot format\n");
fprintf(stderr,"defaults: perf -d1 -m7 -Ntest\n");
			      exit(1);
		    }
		}
	    }
	    else     args.orchname = argv[i];
	}
	else if(args.scorename == NULL) {
	    if(argv[i][0] == '-') {
		switch(argv[i][1]){
		    case 'P': args.scoreP++; break;
		    case 's': args.scores++; break;
		    case 'x': args.scorex++; ++i;
			      args.xfile  = argv[i]; break;
		    default:
fprintf(stderr,"Illegal perf score flag -%c\n",argv[i][1]);
fprintf(stderr,"The legal ones are...\n");
fprintf(stderr,"-P\tC pre processing\n");
fprintf(stderr,"-x fnam\textract from score.srt using extract file 'fnam'\n");
fprintf(stderr,"-s\tscore is in scot format\n");
			      exit(1);
		}
	    }
	    else     args.scorename = argv[i];
	}
	else {
  fprintf(stderr,"perf command error: no flags may occur after score name\n");
	    exit(1);
	}
    }
}
