ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/meta/segment.c
Revision: 1.2
Committed: Sat Nov 15 02:13:37 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1, rad5R3, HEAD
Changes since 1.1: +33 -29 lines
Log Message:
Continued ANSIfication, and reduced other compile warnings.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: segment.c,v 1.1 2003/02/22 02:07:26 greg Exp $";
3 #endif
4 /*
5 * Routines for segment storage and inclusion for meta-files
6 *
7 * 12/18/84
8 */
9
10 #include <string.h>
11
12 #include "rtio.h"
13 #include "meta.h"
14
15
16 #define NODEC 0 /* null declaration (must be 0) */
17
18 #define MAXDEC 2048 /* maximum number of declarations */
19
20 #define NHASH 101 /* hash size (prime) */
21
22
23 static struct declaration {
24 char *sname; /* segment name */
25 PLIST sprims; /* segment primitives */
26 int context; /* declaration containing us */
27 int nexthash; /* next in hash list */
28 } dectabl[MAXDEC];
29
30 static int hashtabl[NHASH];
31
32 static int dectop = 0; /* top of declaration table */
33
34 static int curdec = NODEC; /* current declaration */
35
36
37 static int hash(register char *s);
38 static int lookup(register char *name);
39
40
41
42 static int
43 hash( /* hash a string */
44 register char *s
45 )
46
47 {
48 register int hval = 0;
49
50 while (*s)
51 hval += *s++;
52
53 return(hval % NHASH);
54 }
55
56
57
58
59
60 static int
61 lookup( /* find name in declaration table */
62 register char *name
63 )
64
65 {
66 register int curd;
67
68 if (name == NULL)
69 error(USER, "illegal null segment name in lookup");
70
71 for (curd = hashtabl[hash(name)]; curd != NODEC; curd = dectabl[curd].nexthash)
72 if (strcmp(name, dectabl[curd].sname) == 0)
73 break;
74
75 return(curd);
76 }
77
78
79
80 int
81 inseg(void) /* return TRUE if currently in a segment */
82
83 {
84
85 return(curdec != NODEC);
86 }
87
88
89
90 void
91 openseg( /* open a new segment */
92 char *name
93 )
94
95 {
96 register int olddec;
97
98 if ((olddec = lookup(name)) != NODEC &&
99 dectabl[olddec].context == curdec) /* redefined segment */
100 plfree(&dectabl[olddec].sprims);
101
102 if (++dectop >= MAXDEC)
103 error(SYSTEM, "too many segments in openseg");
104
105 dectabl[dectop].sname = savestr(name);
106 /* save previous context */
107 dectabl[dectop].context = curdec;
108 curdec = dectop;
109
110 }
111
112
113
114
115 void
116 segprim( /* store primitive in current segment */
117 register PRIMITIVE *p
118 )
119
120 {
121 register PRIMITIVE *newp;
122
123 if (!inseg())
124 error(SYSTEM, "illegal call to segprim");
125
126 switch (p->com) {
127
128 case POPEN:
129 openseg(p->args);
130 break;
131
132 case PSEG:
133 segment(p, segprim);
134 break;
135
136 case PCLOSE:
137 closeseg();
138 break;
139
140 default:
141 if ((newp = palloc()) == NULL)
142 error(SYSTEM, "memory limit exceeded in segprim");
143 mcopy((char *)newp, (char *)p, sizeof(PRIMITIVE));
144 newp->args = savestr(p->args);
145 add(newp, &dectabl[curdec].sprims);
146 break;
147 }
148
149 }
150
151
152 void
153 closeseg(void) /* close the current segment */
154
155 {
156 register int i;
157
158 if (!inseg())
159 error(SYSTEM, "illegal call to closeseg");
160
161 /* undefine internal declarations */
162 for (i = dectop; i > curdec; i--) {
163 hashtabl[hash(dectabl[i].sname)] = dectabl[i].nexthash;
164 freestr(dectabl[i].sname);
165 plfree(&dectabl[i].sprims);
166 }
167 dectop = curdec;
168 /* define this declaration */
169 i = hash(dectabl[curdec].sname);
170 dectabl[curdec].nexthash = hashtabl[i];
171 hashtabl[i] = curdec;
172 /* return context */
173 curdec = dectabl[curdec].context;
174 }
175
176
177
178 void
179 segment( /* expand segment p */
180 PRIMITIVE *p,
181 void (*funcp)(PRIMITIVE *p)
182 )
183
184 {
185 int decln;
186 PRIMITIVE curp;
187 register PRIMITIVE *sp;
188
189 if ((decln = lookup(p->args)) == NODEC) {
190 sprintf(errmsg, "reference to undefined segment \"%s\" in segment",
191 p->args);
192 error(USER, errmsg);
193 }
194
195 for (sp = dectabl[decln].sprims.ptop; sp != NULL; sp = sp->pnext)
196
197 if (isglob(sp->com))
198
199 (*funcp)(sp);
200
201 else {
202
203 switch (curp.com = sp->com) {
204
205 case PSEG:
206 case PVSTR:
207 case PTFILL:
208 case PPFILL:
209 curp.arg0 = (sp->arg0 & 0100) |
210 (((sp->arg0 & 060) + p->arg0) & 060);
211 break;
212
213 case PLSEG:
214 if (p->arg0 & 020)
215 curp.arg0 = (~sp->arg0 & 0100) | (sp->arg0 & 060);
216 else
217 curp.arg0 = sp->arg0 & 0160;
218 break;
219
220 default:
221 curp.arg0 = sp->arg0 & 0160;
222 break;
223 }
224 if (p->arg0 & 014)
225 curp.arg0 |= p->arg0 & 014;
226 else
227 curp.arg0 |= sp->arg0 & 014;
228 if (p->arg0 & 03)
229 curp.arg0 |= p->arg0 & 03;
230 else
231 curp.arg0 |= sp->arg0 & 03;
232
233 curp.xy[XMN] = xlate(XMN, sp, p);
234 curp.xy[YMN] = xlate(YMN, sp, p);
235 curp.xy[XMX] = xlate(XMX, sp, p);
236 curp.xy[YMX] = xlate(YMX, sp, p);
237 curp.args = sp->args;
238
239 (*funcp)(&curp);
240 }
241
242 }
243
244
245
246
247
248 int
249 xlate( /* return extrema from p through px */
250 short extrema,
251 PRIMITIVE *p,
252 register PRIMITIVE *px
253 )
254
255 {
256 short oldex;
257 int val;
258
259 if (((oldex = (extrema + 4 - ((px->arg0 >> 4) & 03))%4) ^ extrema) & 02)
260 val = (XYSIZE-1) - p->xy[oldex];
261 else
262 val = p->xy[oldex];
263
264 if (extrema & 01)
265 return(CONV(val, px->xy[YMX] - px->xy[YMN]) + px->xy[YMN]);
266 else
267 return(CONV(val, px->xy[XMX] - px->xy[XMN]) + px->xy[XMN]);
268 }