This is expr.c in view mode; [Download] [Up]
/* General-purpose expr (NOT used by cmusic, but can be used by any program for command line expression arguments, for example (see man 3X expr or help expr) */ #include <stdio.h> #include <math.h> #define LRPN 1000 #define UNOPS "{sin,cos,atan,ln,exp,floor,abs,rand,sqrt}{-}" #define BINOPS "{^,%}{*,/}{+,-}" #define POSTOPS "{dB,K,k,Deg,invs,MM}" #define TWOPI (8.0 * atan(1.0) ) int exprerr = 0; /* error flag */ float expr(string) char *string;{ char *polish(), *rpnp, rpn[LRPN], *it, item[40], sym[40]; int nops, i, n, top = 0; double stack[LRPN]; exprerr = 0; rpnp = rpn; strncpy(rpn,polish(string,UNOPS,BINOPS,POSTOPS),LRPN); while(strlen(rpnp)){ sfield(&rpnp, item, "", ","); it=item; sfield(&it, sym, "", "$"); nops = atoi(it); if(!nops){ if(!index(sym,'.') && *sym == '0'){ if( *(sym+1) == 'x' || *(sym+1) == 'X' ){ sscanf(sym+2, "%x", &n); } else { sscanf(sym, "%o", &n); } stack[++top] = n; } else { if(!sscanf(sym,"%F",&stack[++top]))exprerr++; } continue; } if(nops){ if(!strcmp(sym,"sin")){stack[top] = sin(stack[top]); continue;} if(!strcmp(sym,"cos")){stack[top] = cos(stack[top]); continue;} if(!strcmp(sym,"atan")){stack[top] = atan(stack[top]); continue;} if(!strcmp(sym,"ln")){stack[top] = log(stack[top]); continue;} if(!strcmp(sym,"exp")){stack[top] = exp(stack[top]); continue;} if(!strcmp(sym,"floor")){stack[top] = floor(stack[top]); continue;} if(!strcmp(sym,"abs")){stack[top] = fabs(stack[top]); continue;} if(!strcmp(sym,"sqrt")){stack[top] = sqrt(stack[top]); continue;} if(!strcmp(sym,"rand")){ stack[top] = (double) rand()/(double) 0x7fffffff * stack[top]; continue;} if(!strcmp(sym,"-") && nops == 1){ stack[top] = -stack[top]; continue; } if(!strcmp(sym,"-") && nops == 2){ stack[top-1] = stack[top-1] - stack[top]; top--; continue; } if(!strcmp(sym,"+") && nops == 2){ stack[top-1] = stack[top-1] + stack[top]; top--; continue; } if(!strcmp(sym,"*") && nops == 2){ stack[top-1] = stack[top-1] * stack[top]; top--; continue; } if(!strcmp(sym,"/") && nops == 2){ stack[top-1] = stack[top-1] / stack[top]; top--; continue; } if(!strcmp(sym,"^") && nops == 2){ stack[top-1] = pow( stack[top-1], stack[top]); top--; continue; } if(!strcmp(sym,"%") && nops == 2){ stack[top-1] = (int) stack[top-1] % (int) stack[top]; top--; continue; } if(!strcmp(sym,"dB") && nops == 1){ stack[top] = pow( (double) 10.0, stack[top]/20.); continue; } if(!strcmp(sym,"K") && nops == 1){ stack[top] = stack[top] * 1024.0; continue; } if(!strcmp(sym,"k") && nops == 1){ stack[top] = stack[top] * 1000.0; continue; } if(!strcmp(sym,"Deg") && nops == 1){ stack[top] = stack[top] / 360.0 * TWOPI; continue; } if(!strcmp(sym,"invs") && nops == 1){ if(stack[top]<1.0){stack[top] = 1.0; continue;} n = stack[top]; stack[top] = 0; for(i = 1; i <= n; i++)stack[top] += 1.0/i; continue; } if(!strcmp(sym,"MM") && nops == 1){ stack[top] = 60.0 / stack[top]; continue; } } exprerr++; } if(top != 1)exprerr++; return( (float) stack[top]); } sfield(input,string,iglist,brklist) char **input, *string, *iglist, *brklist;{ int leading, c; leading = 1; 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(c);} } return(NULL); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.