15 |
|
|
16 |
|
#include "random.h" |
17 |
|
|
18 |
+ |
#ifdef SSKIPOPT |
19 |
+ |
/* The following table is used for skipping sources */ |
20 |
+ |
static uby8 *srcskipflags = NULL; /* source inclusion lookup */ |
21 |
+ |
static int ssf_count = 0; /* number of flag entries */ |
22 |
+ |
static int ssf_max = 0; /* current array size */ |
23 |
+ |
static uby8 *ssf_noskip = NULL; /* set of zero flags */ |
24 |
|
|
25 |
+ |
uby8 *ssf_select = NULL; /* sources we may skip */ |
26 |
+ |
|
27 |
+ |
/* Find/allocate source skip flag entry (free all if NULL) */ |
28 |
|
int |
29 |
+ |
sskip_rsi(uby8 *flags) |
30 |
+ |
{ |
31 |
+ |
uby8 *flp; |
32 |
+ |
int i; |
33 |
+ |
|
34 |
+ |
if (flags == NULL) { /* means clear all */ |
35 |
+ |
efree(srcskipflags); srcskipflags = NULL; |
36 |
+ |
ssf_count = ssf_max = 0; |
37 |
+ |
sskip_free(ssf_noskip); |
38 |
+ |
sskip_free(ssf_select); |
39 |
+ |
return(0); |
40 |
+ |
} |
41 |
+ |
if (ssf_noskip == NULL) /* first call? */ |
42 |
+ |
ssf_noskip = sskip_new(); |
43 |
+ |
|
44 |
+ |
if (sskip_eq(flags, ssf_noskip)) |
45 |
+ |
return(-1); /* nothing to skip */ |
46 |
+ |
/* search recent entries */ |
47 |
+ |
flp = srcskipflags + ssf_count*SSKIPFLSIZ; |
48 |
+ |
for (i = ssf_count; i-- > 0; ) |
49 |
+ |
if (sskip_eq(flp -= SSKIPFLSIZ, flags)) |
50 |
+ |
return(-2-i); /* found it! */ |
51 |
+ |
/* else tack on new entry */ |
52 |
+ |
if (ssf_count >= ssf_max) { /* need more space? */ |
53 |
+ |
ssf_max = ssf_count + (ssf_count>>2) + 64; |
54 |
+ |
if (ssf_max <= ssf_count && |
55 |
+ |
(ssf_max = ssf_count+1024) <= ssf_count) |
56 |
+ |
error(SYSTEM, "out of space in sskip_rsi()"); |
57 |
+ |
|
58 |
+ |
srcskipflags = (uby8 *)erealloc(srcskipflags, |
59 |
+ |
ssf_max*SSKIPFLSIZ); |
60 |
+ |
} |
61 |
+ |
sskip_cpy(srcskipflags + ssf_count*SSKIPFLSIZ, flags); |
62 |
+ |
|
63 |
+ |
return(-2 - ssf_count++); /* return index (< -1) */ |
64 |
+ |
} |
65 |
+ |
|
66 |
+ |
/* Get skip flags associated with RAY rsrc index (or NULL) */ |
67 |
+ |
uby8 * |
68 |
+ |
sskip_flags(int rsi) |
69 |
+ |
{ |
70 |
+ |
if (rsi >= -1) |
71 |
+ |
return(ssf_noskip); |
72 |
+ |
|
73 |
+ |
if ((rsi = -2 - rsi) >= ssf_count) |
74 |
+ |
error(CONSISTENCY, "bad index to sskip_flags()"); |
75 |
+ |
|
76 |
+ |
return(srcskipflags + rsi*SSKIPFLSIZ); |
77 |
+ |
} |
78 |
+ |
|
79 |
+ |
/* OR in a second set of flags into a first */ |
80 |
+ |
void |
81 |
+ |
sskip_addflags(uby8 *dfl, const uby8 *sfl) |
82 |
+ |
{ |
83 |
+ |
int nb = SSKIPFLSIZ; |
84 |
+ |
|
85 |
+ |
while (nb--) |
86 |
+ |
*dfl++ |= *sfl++; |
87 |
+ |
} |
88 |
+ |
#endif |
89 |
+ |
|
90 |
+ |
int |
91 |
|
srcskip( /* pre-emptive test for source to skip */ |
92 |
|
int sn, |
93 |
|
RAY *r |
97 |
|
|
98 |
|
if (sp->sflags & SSKIP) |
99 |
|
return(1); |
100 |
< |
|
100 |
> |
#ifdef SSKIPOPT |
101 |
> |
if (r->rsrc < -1 && /* ray has custom skip flags? */ |
102 |
> |
sskip_chk(sskip_flags(r->rsrc), sn)) |
103 |
> |
return(1); |
104 |
> |
#endif |
105 |
|
if ((sp->sflags & (SPROX|SDISTANT)) != SPROX) |
106 |
|
return(0); |
107 |
|
|