Back to index

radiance  4R0+20100331
calc.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: calc.c,v 1.6 2003/12/09 15:55:46 greg Exp $";
00003 #endif
00004 /*
00005  *  calc.c - simple algebraic desk calculator program.
00006  *
00007  *     4/1/86
00008  */
00009 
00010 #include  <stdlib.h>
00011 #include  <stdio.h>
00012 #include  <string.h>
00013 #include  <setjmp.h>
00014 #include  <ctype.h>
00015 
00016 #include  "rterror.h"
00017 #include  "calcomp.h"
00018 
00019 #define  MAXRES             100
00020 
00021 double  result[MAXRES];
00022 int    nres = 0;
00023 
00024 jmp_buf  env;
00025 int  recover = 0;
00026 
00027 
00028 int
00029 main(argc, argv)
00030 int  argc;
00031 char  *argv[];
00032 {
00033        char  expr[2048];
00034        char  *epos;
00035        FILE  *fp;
00036        int  i;
00037        register char  *cp;
00038 
00039        esupport |= E_VARIABLE|E_INCHAN|E_FUNCTION;
00040        esupport &= ~(E_REDEFW|E_RCONST|E_OUTCHAN);
00041 #ifdef  BIGGERLIB
00042        biggerlib();
00043 #endif
00044        varset("PI", ':', 3.14159265358979323846);
00045 
00046        for (i = 1; i < argc; i++)
00047               fcompile(argv[i]);
00048 
00049        setjmp(env);
00050        recover = 1;
00051        eclock++;
00052 
00053        epos = expr;
00054        while (fgets(epos, sizeof(expr)-(epos-expr), stdin) != NULL) {
00055               while (*epos && *epos != '\n')
00056                      epos++;
00057               if (*epos && epos > expr && epos[-1] == '\\') {
00058                      epos[-1] = ' ';
00059                      continue;            /* escaped newline */
00060               }
00061               *epos = '\0';
00062               epos = expr;
00063               switch (expr[0]) {
00064               case '\0':
00065                      continue;
00066               case '?':
00067                      for (cp = expr+1; isspace(*cp); cp++)
00068                             ;
00069                      if (*cp)
00070                             dprint(cp, stdout);
00071                      else
00072                             dprint(NULL, stdout);
00073                      continue;
00074               case '>':
00075                      for (cp = expr+1; isspace(*cp); cp++)
00076                             ;
00077                      if (!*cp) {
00078                             eputs("file name required\n");
00079                             continue;
00080                      }
00081                      if ((fp = fopen(cp, "w")) == NULL) {
00082                             eputs(cp);
00083                             eputs(": cannot open\n");
00084                             continue;
00085                      }
00086                      dprint(NULL, fp);
00087                      fclose(fp);
00088                      continue;
00089               case '<':
00090                      for (cp = expr+1; isspace(*cp); cp++)
00091                             ;
00092                      if (!*cp) {
00093                             eputs("file name required\n");
00094                             continue;
00095                      }
00096                      fcompile(cp);
00097                      eclock++;
00098                      continue;
00099               }
00100               if ((cp = strchr(expr, '=')) != NULL ||
00101                             (cp = strchr(expr, ':')) != NULL) {
00102                      if (cp[1])
00103                             scompile(expr, NULL, 0);
00104                      else if (*cp == '=') {
00105                             *cp = '\0';
00106                             if (!strcmp(expr, "*"))
00107                                    dcleanup(1);
00108                             else
00109                                    dclear(expr);
00110                      } else {
00111                             *cp = '\0';
00112                             if (!strcmp(expr, "*"))
00113                                    dcleanup(2);
00114                             else
00115                                    dremove(expr);
00116                      }
00117                      eclock++;
00118               } else {
00119                      printf("$%d=%.9g\n", nres+1,
00120                                    result[nres%MAXRES] = eval(expr));
00121                      nres++;
00122               }
00123        }
00124 
00125        recover = 0;
00126        quit(0);
00127        return 0; /* pro forma exit */
00128 }
00129 
00130 
00131 double
00132 chanvalue(n)                /* return channel value */
00133 int  n;
00134 {
00135        if (n == 0)
00136               n = nres;
00137        else if (n > nres || nres-n >= MAXRES) {
00138               fprintf(stderr, "$%d: illegal result\n", n);
00139               return(0.0);
00140        }
00141        return(result[(n-1)%MAXRES]);
00142 }
00143 
00144 
00145 void
00146 eputs(msg)
00147 char  *msg;
00148 {
00149        fputs(msg, stderr);
00150 }
00151 
00152 
00153 void
00154 wputs(msg)
00155 char  *msg;
00156 {
00157        eputs(msg);
00158 }
00159 
00160 
00161 void
00162 quit(code)
00163 int  code;
00164 {
00165        if (recover)                /* a cavalier approach */
00166               longjmp(env, 1);
00167        exit(code);
00168 }