ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/calc.c
Revision: 1.10
Committed: Tue Sep 26 18:09:08 2023 UTC (7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 1.9: +21 -1 lines
Error occurred while calculating annotation data.
Log Message:
feat(icalc): Added [context and ] for pushing/popping contexts (mostly to test)

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: calc.c,v 1.9 2023/02/09 21:54:10 greg Exp $";
3 #endif
4 /*
5 * calc.c - simple algebraic desk calculator program.
6 *
7 * 4/1/86
8 */
9
10 #include <stdlib.h>
11 #include <setjmp.h>
12 #include <ctype.h>
13
14 #include "rtio.h"
15 #include "rterror.h"
16 #include "calcomp.h"
17
18 #define MAXRES 100
19
20 double result[MAXRES];
21 int nres = 0;
22
23 jmp_buf env;
24 int recover = 0;
25
26
27 int
28 main(int argc, char *argv[])
29 {
30 char expr[2048];
31 char *epos;
32 FILE *fp;
33 int i;
34 char *cp;
35
36 esupport |= E_VARIABLE|E_INCHAN|E_FUNCTION;
37 esupport &= ~(E_REDEFW|E_RCONST|E_OUTCHAN);
38 #ifdef BIGGERLIB
39 biggerlib();
40 #endif
41 varset("PI", ':', 3.14159265358979323846);
42
43 for (i = 1; i < argc; i++) {
44 cp = getpath(argv[i], getrlibpath(), 0);
45 if (cp == NULL) {
46 eputs(argv[0]);
47 eputs(": cannot find file '");
48 eputs(argv[i]);
49 eputs("'\n");
50 quit(1);
51 }
52 fcompile(cp);
53 }
54 setjmp(env);
55 recover = 1;
56 eclock++;
57
58 epos = expr;
59 while (fgets(epos, sizeof(expr)-(epos-expr), stdin) != NULL) {
60 while (*epos && *epos != '\n')
61 epos++;
62 if (*epos && epos > expr && epos[-1] == '\\') {
63 epos[-1] = ' ';
64 continue; /* escaped newline */
65 }
66 while (epos > expr && isspace(epos[-1]))
67 epos--; /* eliminate end spaces */
68 *epos = '\0';
69 epos = expr;
70 switch (expr[0]) {
71 case '\0':
72 continue;
73 case '?':
74 for (cp = expr+1; isspace(*cp); cp++)
75 ;
76 if (*calcontext(NULL))
77 printf("context is: %s\n", calcontext(NULL));
78 if (*cp)
79 dprint(cp, stdout);
80 else
81 dprint(NULL, stdout);
82 continue;
83 case '>':
84 for (cp = expr+1; isspace(*cp); cp++)
85 ;
86 if (!*cp) {
87 eputs("file name required\n");
88 continue;
89 }
90 if ((fp = fopen(cp, "w")) == NULL) {
91 eputs(cp);
92 eputs(": cannot open\n");
93 continue;
94 }
95 dprint(NULL, fp);
96 fclose(fp);
97 continue;
98 case '<':
99 for (cp = expr+1; isspace(*cp); cp++)
100 ;
101 if (!*cp) {
102 eputs("file name required\n");
103 continue;
104 }
105 cp = getpath(cp, getrlibpath(), 0);
106 if (cp == NULL) {
107 eputs("cannot find file\n");
108 continue;
109 }
110 fcompile(cp);
111 eclock++;
112 continue;
113 case '[':
114 for (cp = expr+1; isspace(*cp); cp++)
115 ;
116 if (!isalpha(*cp)) {
117 eputs("context name required\n");
118 continue;
119 }
120 printf("context now: %s\n", pushcontext(cp));
121 continue;
122 case ']':
123 cp = popcontext();
124 if (*cp)
125 printf("context now: %s\n", cp);
126 else
127 printf("at global context\n");
128 continue;
129 }
130 if ((cp = strchr(expr, '=')) != NULL ||
131 (cp = strchr(expr, ':')) != NULL) {
132 if (cp[1])
133 scompile(expr, NULL, 0);
134 else if (*cp == '=') {
135 *cp = '\0';
136 if (!strcmp(expr, "*"))
137 dcleanup(1);
138 else
139 dclear(expr);
140 } else {
141 *cp = '\0';
142 if (!strcmp(expr, "*"))
143 dcleanup(2);
144 else
145 dremove(expr);
146 }
147 eclock++;
148 } else {
149 printf("$%d=%.9g\n", nres+1,
150 result[nres%MAXRES] = eval(expr));
151 nres++;
152 }
153 }
154
155 recover = 0;
156 quit(0);
157 return 0; /* pro forma exit */
158 }
159
160
161 double
162 chanvalue(n) /* return channel value */
163 int n;
164 {
165 if (n == 0)
166 n = nres;
167 else if (n > nres || nres-n >= MAXRES) {
168 fprintf(stderr, "$%d: illegal result\n", n);
169 return(0.0);
170 }
171 return(result[(n-1)%MAXRES]);
172 }
173
174
175 void
176 eputs(const char *msg)
177 {
178 fputs(msg, stderr);
179 }
180
181
182 void
183 wputs(const char *msg)
184 {
185 eputs(msg);
186 }
187
188
189 void
190 quit(int code)
191 {
192 if (recover) /* a cavalier approach */
193 longjmp(env, 1);
194 exit(code);
195 }