ftp.nice.ch/pub/next/unix/audio/cmusic.bs.N.tar.gz#/src/lib/libdgl/sfexpr.c

This is sfexpr.c in view mode; [Download] [Up]

/*
 * sfexpr - similar to expr() routine from libfrm.a, but optimized for
 * parsing command line for csound.  No major differences, some
 * features left out, such as sin(), ln(), etc.  Postoperators added:
 * s - seconds, S - samples, K - 1024, ms - milliseconds, m - minutes,
 * dB. 
 */

#include <stdio.h>
#include <carl/sndio.h>
#include <math.h>

#define LRPN 200
#define UNOPS "{-}"
#define BINOPS "{^,%}{*,/}{+,-}"
#define POSTOPS "{dB,K,k,S,s,m,ms}"
#define TWOPI (8.0 * atan(1.0) )

float sfexpr(string, timefac)  
	char *string; float timefac;
{
    char *polish(), *rpnp, rpn[LRPN], *it, item[40], sym[40];
    int nops, n, top = 0;
    double stack[LRPN];

    rpnp = rpn;
    strncpy(rpn,polish(string,UNOPS,BINOPS,POSTOPS),LRPN);

    while(strlen(rpnp))
	{
	sffield(&rpnp, item, "", ",");
	it=item;
	sffield(&it, sym, "", "$");
	nops = atoi(it);
	if (!nops)	/* it is a constant number */
	    {
	    if(!index(sym,'.') && *sym == '0') /* no '.' and '0' prefix */
		{
		if( *(sym+1) == 'x' || *(sym+1) == 'X' ) 
		    sscanf(sym+2, "%x", &n);
		else sscanf(sym, "%o", &n);
		    stack[++top] = n;
	        } 
	    else 
		sscanf(sym,"%F",&stack[++top]);
	    stack[top] *= timefac;
	    continue;
	    }
	/* from here on, deal with operators only */
	if (!strcmp(sym,"-") && nops == 1)
	    {
	    stack[top] = -stack[top];
	    continue;
	    }
	else
	if (nops == 2)
	    {
	    switch(sym[0])
		{
		case '-':
		    stack[top-1] = stack[top-1] - stack[top];
		    break;
		case '+':
		    stack[top-1] = stack[top-1] + stack[top];
		    break;
		case '*':
		    stack[top-1] = stack[top-1] * stack[top];
		    break;
		case '/':
		    stack[top-1] = stack[top-1] / stack[top];
		    break;
		case '^':
		    stack[top-1] = pow(stack[top-1], stack[top]);
		    break;
		case '%':
		    stack[top-1] = (int) stack[top-1] % (int) stack[top];
		}
	    top--;
	    }
	else
	if (nops == 1)
	    {
	    if(!strcmp(sym,"dB")){
		stack[top] /= timefac;
		stack[top] = pow( (double) 10.0, stack[top]/20.);
		continue;
		}
	    if(!strcmp(sym,"K")){
		stack[top] *= 1024.0;
		continue;
		}
	    if(!strcmp(sym,"k")){
		stack[top] *= 1000.0;
		continue;
		}
	    if(!strcmp(sym,"S")){
		stack[top] /= timefac;
		continue;
		}
	    if(!strcmp(sym,"ms")){
		stack[top] *= 0.001;
		continue;
		}
	    if(!strcmp(sym,"m")){
		stack[top] *= 60.0;
		continue;
		}
	    if(!strcmp(sym,"s")){
		continue;
		}
	    }
	}
    return( (float) stack[top]);
    }

sffield(input, string, iglist, brklist) 
	char **input, *string, *iglist, *brklist;
{
	int leading = 1, c;
	while ((c = *(*input)++) != NULL) {
		if (leading && c==' ')
			continue;
		if (index(iglist,c))
			continue;
		if (!index(brklist,c)){
			*string++ = c; 
			leading = 0; 
			continue;
		}
		else {
			*string = NULL; 
			return;
		}
	}
	 return; 
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.