1 /*
2 * Copyright (c) Tony Bybell 1999-2018.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 */
9
10 #include "globals.h"
11 #include <config.h>
12 #include "analyzer.h"
13 #include "currenttime.h"
14 #include "symbol.h"
15 #include "bsearch.h"
16 #include "strace.h"
17 #include "hierpack.h"
18 #include <ctype.h>
19
compar_timechain(const void * s1,const void * s2)20 static int compar_timechain(const void *s1, const void *s2)
21 {
22 TimeType key, obj, delta;
23 TimeType *cpos;
24 int rv;
25
26 key=*((TimeType *)s1);
27 obj=*(cpos=(TimeType *)s2);
28
29 if((obj<=key)&&(obj>GLOBALS->max_compare_time_tc_bsearch_c_1))
30 {
31 GLOBALS->max_compare_time_tc_bsearch_c_1=obj;
32 GLOBALS->max_compare_pos_tc_bsearch_c_1=cpos;
33 }
34
35 delta=key-obj;
36 if(delta<0) rv=-1;
37 else if(delta>0) rv=1;
38 else rv=0;
39
40 return(rv);
41 }
42
bsearch_timechain(TimeType key)43 int bsearch_timechain(TimeType key)
44 {
45 GLOBALS->max_compare_time_tc_bsearch_c_1=-2; GLOBALS->max_compare_pos_tc_bsearch_c_1=NULL;
46
47 if(!GLOBALS->strace_ctx->timearray) return(-1);
48
49 if(bsearch(&key, GLOBALS->strace_ctx->timearray, GLOBALS->strace_ctx->timearray_size, sizeof(TimeType), compar_timechain))
50 {
51 /* nothing, all side effects are in bsearch */
52 }
53
54 if((!GLOBALS->max_compare_pos_tc_bsearch_c_1)||(GLOBALS->max_compare_time_tc_bsearch_c_1<GLOBALS->shift_timebase))
55 {
56 GLOBALS->max_compare_pos_tc_bsearch_c_1=GLOBALS->strace_ctx->timearray; /* aix bsearch fix */
57 }
58
59 return(GLOBALS->max_compare_pos_tc_bsearch_c_1-GLOBALS->strace_ctx->timearray);
60 }
61
62 /*****************************************************************************************/
63
bsearch_aetinfo_timechain(TimeType key)64 int bsearch_aetinfo_timechain(TimeType key)
65 {
66 GLOBALS->max_compare_time_tc_bsearch_c_1=-2; GLOBALS->max_compare_pos_tc_bsearch_c_1=NULL;
67
68 if(!GLOBALS->ae2_time_xlate) return(-1);
69
70 if(bsearch(&key, GLOBALS->ae2_time_xlate, GLOBALS->ae2_end_cyc - GLOBALS->ae2_start_cyc + 1, sizeof(TimeType), compar_timechain))
71 {
72 /* nothing, all side effects are in bsearch */
73 }
74
75 if(!GLOBALS->max_compare_pos_tc_bsearch_c_1)
76 {
77 GLOBALS->max_compare_pos_tc_bsearch_c_1=GLOBALS->ae2_time_xlate; /* aix bsearch fix */
78 }
79
80 return(GLOBALS->max_compare_pos_tc_bsearch_c_1-GLOBALS->ae2_time_xlate);
81 }
82
83 /*****************************************************************************************/
84
compar_histent(const void * s1,const void * s2)85 static int compar_histent(const void *s1, const void *s2)
86 {
87 TimeType key, obj, delta;
88 hptr cpos;
89 int rv;
90
91 key=*((TimeType *)s1);
92 obj=(cpos=(*((hptr *)s2)))->time;
93
94 if((obj<=key)&&(obj>GLOBALS->max_compare_time_bsearch_c_1))
95 {
96 GLOBALS->max_compare_time_bsearch_c_1=obj;
97 GLOBALS->max_compare_pos_bsearch_c_1=cpos;
98 GLOBALS->max_compare_index=(hptr *)s2;
99 }
100
101 delta=key-obj;
102 if(delta<0) rv=-1;
103 else if(delta>0) rv=1;
104 else rv=0;
105
106 return(rv);
107 }
108
bsearch_node(nptr n,TimeType key)109 hptr bsearch_node(nptr n, TimeType key)
110 {
111 GLOBALS->max_compare_time_bsearch_c_1=-2; GLOBALS->max_compare_pos_bsearch_c_1=NULL; GLOBALS->max_compare_index=NULL;
112
113 if(bsearch(&key, n->harray, n->numhist, sizeof(hptr), compar_histent))
114 {
115 /* nothing, all side effects are in bsearch */
116 }
117
118 if((!GLOBALS->max_compare_pos_bsearch_c_1)||(GLOBALS->max_compare_time_bsearch_c_1<LLDescriptor(0)))
119 {
120 GLOBALS->max_compare_pos_bsearch_c_1=n->harray[1]; /* aix bsearch fix */
121 GLOBALS->max_compare_index=&(n->harray[1]);
122 }
123
124 while(GLOBALS->max_compare_pos_bsearch_c_1->next) /* non-RoSync dumper deglitching fix */
125 {
126 if(GLOBALS->max_compare_pos_bsearch_c_1->time != GLOBALS->max_compare_pos_bsearch_c_1->next->time) break;
127 GLOBALS->max_compare_pos_bsearch_c_1 = GLOBALS->max_compare_pos_bsearch_c_1->next;
128 }
129
130 return(GLOBALS->max_compare_pos_bsearch_c_1);
131 }
132
133 /*****************************************************************************************/
134
135
compar_vectorent(const void * s1,const void * s2)136 static int compar_vectorent(const void *s1, const void *s2)
137 {
138 TimeType key, obj, delta;
139 vptr cpos;
140 int rv;
141
142 key=*((TimeType *)s1);
143 /* obj=(cpos=(*((vptr *)s2)))->time+GLOBALS->shift_timebase; */
144
145 obj=(cpos=(*((vptr *)s2)))->time;
146
147 if((obj<=key)&&(obj>GLOBALS->vmax_compare_time_bsearch_c_1))
148 {
149 GLOBALS->vmax_compare_time_bsearch_c_1=obj;
150 GLOBALS->vmax_compare_pos_bsearch_c_1=cpos;
151 GLOBALS->vmax_compare_index=(vptr *)s2;
152 }
153
154 delta=key-obj;
155 if(delta<0) rv=-1;
156 else if(delta>0) rv=1;
157 else rv=0;
158
159 return(rv);
160 }
161
bsearch_vector(bvptr b,TimeType key)162 vptr bsearch_vector(bvptr b, TimeType key)
163 {
164 GLOBALS->vmax_compare_time_bsearch_c_1=-2; GLOBALS->vmax_compare_pos_bsearch_c_1=NULL; GLOBALS->vmax_compare_index=NULL;
165
166 if(bsearch(&key, b->vectors, b->numregions, sizeof(vptr), compar_vectorent))
167 {
168 /* nothing, all side effects are in bsearch */
169 }
170
171 if((!GLOBALS->vmax_compare_pos_bsearch_c_1)||(GLOBALS->vmax_compare_time_bsearch_c_1<LLDescriptor(0)))
172 {
173 /* ignore warning: array index of '1' indexes past the end of an array (that contains 1 elements) [-Warray-bounds] */
174 /* because this array is allocated with size > that declared in the structure definition via end of structure malloc padding */
175 GLOBALS->vmax_compare_pos_bsearch_c_1=b->vectors[1]; /* aix bsearch fix */
176 GLOBALS->vmax_compare_index=&(b->vectors[1]);
177 }
178
179 while(GLOBALS->vmax_compare_pos_bsearch_c_1->next) /* non-RoSync dumper deglitching fix */
180 {
181 if(GLOBALS->vmax_compare_pos_bsearch_c_1->time != GLOBALS->vmax_compare_pos_bsearch_c_1->next->time) break;
182 GLOBALS->vmax_compare_pos_bsearch_c_1 = GLOBALS->vmax_compare_pos_bsearch_c_1->next;
183 }
184
185 return(GLOBALS->vmax_compare_pos_bsearch_c_1);
186 }
187
188 /*****************************************************************************************/
189
190
compar_trunc(const void * s1,const void * s2)191 static int compar_trunc(const void *s1, const void *s2)
192 {
193 char *str;
194 char vcache[2];
195 int key, obj;
196
197 str=(char *)s2;
198 key=*((int*)s1);
199
200 vcache[0]=*str;
201 vcache[1]=*(str+1);
202 *str='+';
203 *(str+1)=0;
204 obj=font_engine_string_measure(GLOBALS->wavefont,GLOBALS->trunc_asciibase_bsearch_c_1);
205 *str=vcache[0];
206 *(str+1)=vcache[1];
207
208 if((obj<=key)&&(obj>GLOBALS->maxlen_trunc))
209 {
210 GLOBALS->maxlen_trunc=obj;
211 GLOBALS->maxlen_trunc_pos_bsearch_c_1=str;
212 }
213
214 return(key-obj);
215 }
216
217
bsearch_trunc(char * ascii,int maxlen)218 char *bsearch_trunc(char *ascii, int maxlen)
219 {
220 int len;
221
222 if((maxlen<=0)||(!ascii)||(!(len=strlen(ascii)))) return(NULL);
223
224 GLOBALS->maxlen_trunc_pos_bsearch_c_1=NULL;
225
226 if(GLOBALS->wavefont->is_mono)
227 {
228 int adjusted_len = maxlen / GLOBALS->wavefont->mono_width;
229 if(adjusted_len) adjusted_len--;
230 if(GLOBALS->wavefont->mono_width <= maxlen)
231 {
232 GLOBALS->maxlen_trunc_pos_bsearch_c_1 = ascii + adjusted_len;
233 }
234 }
235 else
236 {
237 GLOBALS->maxlen_trunc=0;
238
239 if(bsearch(&maxlen, GLOBALS->trunc_asciibase_bsearch_c_1=ascii, len, sizeof(char), compar_trunc))
240 {
241 /* nothing, all side effects are in bsearch */
242 }
243 }
244
245 return(GLOBALS->maxlen_trunc_pos_bsearch_c_1);
246 }
247
248
bsearch_trunc_print(char * ascii,int maxlen)249 char *bsearch_trunc_print(char *ascii, int maxlen)
250 {
251 int len;
252
253 if((maxlen<=0)||(!ascii)||(!(len=strlen(ascii)))) return(NULL);
254
255 GLOBALS->maxlen_trunc=0; GLOBALS->maxlen_trunc_pos_bsearch_c_1=NULL;
256
257 if(bsearch(&maxlen, GLOBALS->trunc_asciibase_bsearch_c_1=ascii, len, sizeof(char), compar_trunc))
258 {
259 /* nothing, all side effects are in bsearch */
260 }
261
262 return(GLOBALS->maxlen_trunc_pos_bsearch_c_1);
263 }
264
265
266 /*****************************************************************************************/
267
compar_facs(const void * key,const void * v2)268 static int compar_facs(const void *key, const void *v2)
269 {
270 struct symbol *s2;
271 int rc;
272 int was_packed = HIER_DEPACK_STATIC;
273 char *s3;
274
275 s2=*((struct symbol **)v2);
276 s3 = hier_decompress_flagged(s2->name, &was_packed);
277 rc=sigcmp((char *)key,s3);
278
279 /* if(was_packed) free_2(s3); ...not needed with HIER_DEPACK_STATIC */
280
281 return(rc);
282 }
283
bsearch_facs(char * ascii,unsigned int * rows_return)284 struct symbol *bsearch_facs(char *ascii, unsigned int *rows_return)
285 {
286 struct symbol **rc;
287 int len;
288
289 if ((!ascii)||(!(len=strlen(ascii)))) return(NULL);
290 if(rows_return)
291 {
292 *rows_return = 0;
293 }
294
295 if(ascii[len-1]=='}')
296 {
297 int i;
298
299 for(i=len-2;i>=2;i--)
300 {
301 if(isdigit((int)(unsigned char)ascii[i])) continue;
302 if(ascii[i]=='{')
303 {
304 char *tsc = wave_alloca(i+1);
305 memcpy(tsc, ascii, i+1);
306 tsc[i] = 0;
307 rc=(struct symbol **)bsearch(tsc, GLOBALS->facs, GLOBALS->numfacs, sizeof(struct symbol *), compar_facs);
308 if(rc)
309 {
310 unsigned int whichrow = atoi(&ascii[i+1]);
311 if(rows_return) *rows_return = whichrow;
312
313 #ifdef WAVE_ARRAY_SUPPORT
314 if(whichrow <= (*rc)->n->array_height)
315 #endif
316 {
317 return(*rc);
318 }
319 }
320 }
321 break; /* fallthrough to normal handler */
322 }
323
324 }
325
326 rc=(struct symbol **)bsearch(ascii, GLOBALS->facs, GLOBALS->numfacs, sizeof(struct symbol *), compar_facs);
327 if(rc) return(*rc); else return(NULL);
328 }
329