FreeWRL / FreeX3D 4.3.0
utils.c
1/*
2
3 General utility functions.
4
5*/
6
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27
28
29#include <config.h>
30#include <system.h>
31#include <display.h>
32#include <internal.h>
33
34#include <libFreeWRL.h>
35
36#include "../vrml_parser/Structs.h"
37#include "headers.h"
38
39
40char *BrowserFullPath = NULL;
41char *BrowserName = "FreeWRL VRML/X3D Browser";
42
43static unsigned int fps_histo[120];
44static int collect_fps_histo = 0;
45void fps_histo_print(){
46 int i;
47 for(i=0;i<120;i++){
48 printf("%3d %d\n",i,fps_histo[i]);
49 fps_histo[i]=0;
50 }
51}
52void fps_histo_toggle(){
53 if(collect_fps_histo == 0){
54 printf("turning on fps histo collection - hit H again to print and end\n");
55 collect_fps_histo = 1;
56 }else if(collect_fps_histo == 1){
57 printf("fps histo:\n");
58 fps_histo_print();
59 collect_fps_histo = 0;
60 }
61}
62void fps_histo_collect(){
63 if(collect_fps_histo == 1){
64 double dt, fps;
65 dt = TickTime() - lastTime();
66 fps = 1.0/dt;
67 if(fps < 0.0)
68 fps_histo[0] +=1;
69 else if(fps > 119.0)
70 fps_histo[119] +=1;
71 else
72 fps_histo[(int)fps] +=1;
73
74 }
75}
76
77const char* freewrl_get_browser_program()
78{
79 char *tmp;
80
81 /*
82 1. Check BROWSER environment variable
83 2. Use configuration value BROWSER
84 */
85
86 tmp = getenv("BROWSER");
87 if (!tmp) {
88 tmp = BROWSER;
89 }
90 return tmp;
91}
92
93#define Boolean int
94
95/* Return DEFed name from its node, or NULL if not found */
96int isNodeDEFedYet(struct X3D_Node *node, Stack *DEFedNodes)
97{
98 int ind;
99 if(DEFedNodes == NULL) return 0;
100 for (ind=0; ind < DEFedNodes->n; ind++) {
101 /* did we find this index? */
102 if (vector_get(struct X3D_Node*, DEFedNodes, ind) == node) {
103 return 1;
104 }
105 }
106 return 0;
107}
108
109char * dontRecurseList [] = {
110 "_sortedChildren",
111 NULL,
112};
113int doRecurse(const char *fieldname){
114 int dont, j;
115 dont = 0;
116 j=0;
117 while(dontRecurseList[j] != NULL)
118 {
119 dont = dont || !strcmp(dontRecurseList[j],fieldname);
120 j++;
121 }
122 return dont == 0 ? 1 : 0;
123}
129void Multi_String_print(struct Multi_String *url)
130{
131 if (url) {
132 if (!url->p) {
133 PRINTF("multi url: <empty>");
134 } else {
135 int i;
136
137 PRINTF("multi url: ");
138 for (i = 0; i < url->n; i++) {
139 struct Uni_String *s = url->p[i];
140 PRINTF("[%d] %s", i, s->strptr);
141 }
142 }
143 PRINTF("\n");
144 }
145}
146void print_field_value(FILE *fp, int typeIndex, union anyVrml* value)
147{
148 int i;
149 switch(typeIndex)
150 {
151 case FIELDTYPE_FreeWRLPTR:
152 {
153 fprintf(fp," %p \n",(void *)value);
154 break;
155 }
156 case FIELDTYPE_SFNode:
157 {
158 fprintf(fp," %p \n",(void *)value);
159 break;
160 }
161 case FIELDTYPE_MFNode:
162 {
163 int j;
164 struct Multi_Node* mfnode;
165 mfnode = (struct Multi_Node*)value;
166 fprintf(fp,"{ ");
167 for(j=0;j<mfnode->n;j++)
168 fprintf(fp," %p, ",mfnode->p[j]);
169 break;
170 }
171 case FIELDTYPE_SFString:
172 {
173 struct Uni_String** sfstring = (struct Uni_String**)value;
174 fprintf (fp," %s ",(*sfstring)->strptr);
175 break;
176 }
177 case FIELDTYPE_MFString:
178 {
179 struct Multi_String* mfstring = (struct Multi_String*)value;
180 fprintf (fp," { ");
181 for (i=0; i<mfstring->n; i++) { fprintf (fp,"%s, ",mfstring->p[i]->strptr); }
182 fprintf(fp,"}");
183 break;
184 }
185 case FIELDTYPE_SFFloat:
186 {
187 float *flt = (float*)value;
188 fprintf(fp," %4.3f ",*flt);
189 break;
190 }
191 case FIELDTYPE_MFFloat:
192 {
193 struct Multi_Float *mffloat = (struct Multi_Float*)value;
194 fprintf (fp,"{ ");
195 for (i=0; i<mffloat->n; i++) { fprintf (fp," %4.3f,",mffloat->p[i]); }
196 fprintf(fp,"}");
197 break;
198 }
199 case FIELDTYPE_SFTime:
200 case FIELDTYPE_SFDouble:
201 {
202 double *sftime = (double*)value;
203 fprintf (fp,"%4.3f",*sftime);
204 break;
205 }
206 case FIELDTYPE_MFTime:
207 case FIELDTYPE_MFDouble:
208 {
209 struct Multi_Double *mfdouble = (struct Multi_Double*)value;
210 fprintf (fp,"{");
211 for (i=0; i<mfdouble->n; i++) { fprintf (fp," %4.3f,",mfdouble->p[i]); }
212 fprintf(fp,"}");
213 break;
214 }
215 case FIELDTYPE_SFInt32:
216 case FIELDTYPE_SFBool:
217 {
218 int *sfint32 = (int*)(value);
219 fprintf (fp," \t%d\n",*sfint32);
220 break;
221 }
222 case FIELDTYPE_MFInt32:
223 case FIELDTYPE_MFBool:
224 {
225 struct Multi_Int32 *mfint32 = (struct Multi_Int32*)value;
226 fprintf (fp,"{");
227 for (i=0; i<mfint32->n; i++) { fprintf (fp," %d,",mfint32->p[i]); }
228 fprintf(fp,"}");
229 break;
230 }
231 case FIELDTYPE_SFVec2f:
232 {
233 struct SFVec2f * sfvec2f = (struct SFVec2f *)value;
234 for (i=0; i<2; i++) { fprintf (fp,"%4.3f ",sfvec2f->c[i]); }
235 break;
236 }
237 case FIELDTYPE_MFVec2f:
238 {
239 struct Multi_Vec2f *mfvec2f = (struct Multi_Vec2f*)value;
240 fprintf (fp,"{");
241 for (i=0; i<mfvec2f->n; i++)
242 { fprintf (fp,"[%4.3f, %4.3f],",mfvec2f->p[i].c[0], mfvec2f->p[i].c[1]); }
243 fprintf(fp,"}");
244 break;
245 }
246 case FIELDTYPE_SFVec2d:
247 {
248 struct SFVec2d * sfvec2d = (struct SFVec2d *)value;
249 for (i=0; i<2; i++) { fprintf (fp,"%4.3f, ",sfvec2d->c[i]); }
250 break;
251 }
252 case FIELDTYPE_MFVec2d:
253 {
254 struct Multi_Vec2d *mfvec2d = (struct Multi_Vec2d*)value;
255 fprintf (fp,"{");
256 for (i=0; i<mfvec2d->n; i++)
257 { fprintf (fp,"[%4.3f, %4.3f], ",mfvec2d->p[i].c[0], mfvec2d->p[i].c[1]); }
258 fprintf(fp,"}");
259 break;
260 }
261 case FIELDTYPE_SFVec3f:
262 case FIELDTYPE_SFColor:
263 {
264 struct SFVec3f * sfvec3f = (struct SFVec3f *)value;
265 for (i=0; i<3; i++) { fprintf (fp,"%4.3f ",sfvec3f->c[i]); }
266 break;
267 }
268 case FIELDTYPE_MFVec3f:
269 case FIELDTYPE_MFColor:
270 {
271 struct Multi_Vec3f *mfvec3f = (struct Multi_Vec3f*)value;
272 fprintf (fp,"{");
273 for (i=0; i<mfvec3f->n; i++)
274 { fprintf (fp,"[%4.3f, %4.3f, %4.3f],",mfvec3f->p[i].c[0], mfvec3f->p[i].c[1],mfvec3f->p[i].c[2]); }
275 fprintf(fp,"}");
276 break;
277 }
278 case FIELDTYPE_SFVec3d:
279 {
280 struct SFVec3d * sfvec3d = (struct SFVec3d *)value;
281 for (i=0; i<3; i++) { fprintf (fp,"%4.3f ",sfvec3d->c[i]); }
282 break;
283 }
284 case FIELDTYPE_MFVec3d:
285 {
286 struct Multi_Vec3d *mfvec3d = (struct Multi_Vec3d*)value;
287 fprintf (fp,"{");
288 for (i=0; i<mfvec3d->n; i++)
289 { fprintf (fp,"[%4.3f, %4.3f, %4.3f],",mfvec3d->p[i].c[0], mfvec3d->p[i].c[1],mfvec3d->p[i].c[2]); }
290 fprintf(fp,"}");
291 break;
292 }
293 case FIELDTYPE_SFVec4f:
294 case FIELDTYPE_SFColorRGBA:
295 case FIELDTYPE_SFRotation:
296 {
297 struct SFRotation * sfrot = (struct SFRotation *)value;
298 for (i=0; i<4; i++) { fprintf (fp,"%4.3f ",sfrot->c[i]); }
299 break;
300 }
301 case FIELDTYPE_MFVec4f:
302 case FIELDTYPE_MFColorRGBA:
303 case FIELDTYPE_MFRotation:
304 {
305 struct Multi_ColorRGBA *mfrgba = (struct Multi_ColorRGBA*)value;
306 fprintf (fp,"{");
307 for (i=0; i<mfrgba->n; i++)
308 { fprintf (fp,"[%4.3f, %4.3f, %4.3f, %4.3f]\n",mfrgba->p[i].c[0], mfrgba->p[i].c[1],mfrgba->p[i].c[2],mfrgba->p[i].c[3]); }
309 fprintf(fp,"}");
310 break;
311 }
312 case FIELDTYPE_SFVec4d:
313 {
314 struct SFVec4d * sfvec4d = (struct SFVec4d *)value;
315 for (i=0; i<4; i++) { fprintf (fp,"%4.3f ",sfvec4d->c[i]); }
316 break;
317 }
318 case FIELDTYPE_MFVec4d:
319 {
320 struct Multi_Vec4d *mfvec4d = (struct Multi_Vec4d*)value;
321 fprintf (fp,"{");
322 for (i=0; i<mfvec4d->n; i++)
323 { fprintf (fp,"[%4.3f, %4.3f, %4.3f, %4.3f],",mfvec4d->p[i].c[0], mfvec4d->p[i].c[1],mfvec4d->p[i].c[2],mfvec4d->p[i].c[3]); }
324 fprintf(fp,"}");
325 break;
326 }
327 case FIELDTYPE_SFMatrix3f:
328 {
329 struct SFMatrix3f *sfmat3f = (struct SFMatrix3f*)value;
330 fprintf (fp," [%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
331 sfmat3f->c[0],sfmat3f->c[1],sfmat3f->c[2],
332 sfmat3f->c[3],sfmat3f->c[4],sfmat3f->c[5],
333 sfmat3f->c[6],sfmat3f->c[7],sfmat3f->c[8]);
334 break;
335 }
336 case FIELDTYPE_MFMatrix3f:
337 {
338 struct Multi_Matrix3f *mfmat3f = (struct Multi_Matrix3f*)value;
339 fprintf (fp,"{");
340 for (i=0; i<mfmat3f->n; i++) {
341 fprintf (fp,"[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ],",
342 mfmat3f->p[i].c[0],mfmat3f->p[i].c[1],mfmat3f->p[i].c[2],
343 mfmat3f->p[i].c[3],mfmat3f->p[i].c[4],mfmat3f->p[i].c[5],
344 mfmat3f->p[i].c[6],mfmat3f->p[i].c[7],mfmat3f->p[i].c[8]); }
345 fprintf(fp,"}");
346 break;
347 }
348 case FIELDTYPE_SFMatrix3d:
349 {
350 struct SFMatrix3d *sfmat3d = (struct SFMatrix3d*)value;
351 fprintf (fp," [%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]",
352 sfmat3d->c[0],sfmat3d->c[1],sfmat3d->c[2],
353 sfmat3d->c[3],sfmat3d->c[4],sfmat3d->c[5],
354 sfmat3d->c[6],sfmat3d->c[7],sfmat3d->c[8]);
355 break;
356 }
357 case FIELDTYPE_MFMatrix3d:
358 {
359 struct Multi_Matrix3d *mfmat3d = (struct Multi_Matrix3d*)value;
360 fprintf (fp,"{");
361 for (i=0; i<mfmat3d->n; i++) {
362 fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",i,
363 mfmat3d->p[i].c[0],mfmat3d->p[i].c[1],mfmat3d->p[i].c[2],
364 mfmat3d->p[i].c[3],mfmat3d->p[i].c[4],mfmat3d->p[i].c[5],
365 mfmat3d->p[i].c[6],mfmat3d->p[i].c[7],mfmat3d->p[i].c[8]); }
366 break;
367 }
368 case FIELDTYPE_SFMatrix4f:
369 {
370 struct SFMatrix4f *sfmat4f = (struct SFMatrix4f*)value;
371 fprintf (fp," \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
372 sfmat4f->c[0],sfmat4f->c[1],sfmat4f->c[2],sfmat4f->c[3],
373 sfmat4f->c[4],sfmat4f->c[5],sfmat4f->c[6],sfmat4f->c[7],
374 sfmat4f->c[8],sfmat4f->c[9],sfmat4f->c[10],sfmat4f->c[11],
375 sfmat4f->c[12],sfmat4f->c[13],sfmat4f->c[14],sfmat4f->c[15]);
376 break;
377 }
378 case FIELDTYPE_MFMatrix4f:
379 {
380 struct Multi_Matrix4f *mfmat4f = (struct Multi_Matrix4f*)value;
381 fprintf (fp,"{");
382 for (i=0; i<mfmat4f->n; i++) {
383 fprintf (fp,"[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ],",
384 mfmat4f->p[i].c[0],mfmat4f->p[i].c[1],mfmat4f->p[i].c[2],mfmat4f->p[i].c[3],
385 mfmat4f->p[i].c[4],mfmat4f->p[i].c[5],mfmat4f->p[i].c[6],mfmat4f->p[i].c[7],
386 mfmat4f->p[i].c[8],mfmat4f->p[i].c[9],mfmat4f->p[i].c[10],mfmat4f->p[i].c[11],
387 mfmat4f->p[i].c[12],mfmat4f->p[i].c[13],mfmat4f->p[i].c[14],mfmat4f->p[i].c[15]); }
388 fprintf(fp,"}");
389 break;
390 }
391 case FIELDTYPE_SFMatrix4d:
392 {
393 struct SFMatrix4d *sfmat4d = (struct SFMatrix4d*)value;
394 fprintf (fp," [%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]",
395 sfmat4d->c[0],sfmat4d->c[1],sfmat4d->c[2],sfmat4d->c[3],
396 sfmat4d->c[4],sfmat4d->c[5],sfmat4d->c[6],sfmat4d->c[7],
397 sfmat4d->c[8],sfmat4d->c[9],sfmat4d->c[10],sfmat4d->c[11],
398 sfmat4d->c[12],sfmat4d->c[13],sfmat4d->c[14],sfmat4d->c[15]);
399 break;
400 }
401 case FIELDTYPE_MFMatrix4d:
402 {
403 struct Multi_Matrix4d *mfmat4d = (struct Multi_Matrix4d*)value;
404 fprintf (fp,"{");
405 for (i=0; i<mfmat4d->n; i++) {
406 fprintf (fp,"[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ],",
407 mfmat4d->p[i].c[0],mfmat4d->p[i].c[1],mfmat4d->p[i].c[2],mfmat4d->p[i].c[3],
408 mfmat4d->p[i].c[4],mfmat4d->p[i].c[5],mfmat4d->p[i].c[6],mfmat4d->p[i].c[7],
409 mfmat4d->p[i].c[8],mfmat4d->p[i].c[9],mfmat4d->p[i].c[10],mfmat4d->p[i].c[11],
410 mfmat4d->p[i].c[12],mfmat4d->p[i].c[13],mfmat4d->p[i].c[14],mfmat4d->p[i].c[15]); }
411 fprintf(fp,"}");
412 break;
413 }
414
415 case FIELDTYPE_SFImage:
416 {
417 fprintf(fp," %p ",(void *)value); //no SFImage struct defined
418 break;
419 }
420 }
421} //return print_field
422void dump_scene(FILE *fp, int level, struct X3D_Node* node);
423void dump_scene2(FILE *fp, int level, struct X3D_Node* node, int recurse, Stack *DEFedNodes);
424// print_field is used by dump_scene2() to pretty-print a single field.
425// recurses into dump_scene2 for SFNode and MFNodes to print them in detail.
426void print_field(FILE *fp,int level, int typeIndex, const char* fieldName, union anyVrml* value, Stack* DEFedNodes)
427{
428 int lc, i;
429 #define spacer for (lc=0; lc<level; lc++) fprintf (fp," ");
430
431 switch(typeIndex)
432 {
433 case FIELDTYPE_FreeWRLPTR:
434 {
435 fprintf(fp," %p \n",(void *)value);
436 break;
437 }
438 case FIELDTYPE_SFNode:
439 {
440 int dore;
441 struct X3D_Node** sfnode = (struct X3D_Node**)value;
442 dore = doRecurse(fieldName);
443 fprintf (fp,":\n"); dump_scene2(fp,level+1,*sfnode,dore,DEFedNodes);
444 break;
445 }
446 case FIELDTYPE_MFNode:
447 {
448 int j, dore;
449 struct Multi_Node* mfnode;
450 dore = doRecurse(fieldName);
451 mfnode = (struct Multi_Node*)value;
452 fprintf(fp,":\n");
453 for(j=0;j<mfnode->n;j++)
454 dump_scene2(fp,level+1,mfnode->p[j],dore,DEFedNodes);
455 break;
456 }
457 case FIELDTYPE_SFString:
458 {
459 struct Uni_String** sfstring = (struct Uni_String**)value;
460 fprintf (fp," \t%s\n",(*sfstring)->strptr);
461 break;
462 }
463 case FIELDTYPE_MFString:
464 {
465 struct Multi_String* mfstring = (struct Multi_String*)value;
466 fprintf (fp," : \n");
467 for (i=0; i<mfstring->n; i++) { spacer fprintf (fp," %d: \t%s\n",i,mfstring->p[i]->strptr); }
468 break;
469 }
470 case FIELDTYPE_SFFloat:
471 {
472 float *flt = (float*)value;
473 fprintf (fp," \t%4.3f\n",*flt);
474 break;
475 }
476 case FIELDTYPE_MFFloat:
477 {
478 struct Multi_Float *mffloat = (struct Multi_Float*)value;
479 fprintf (fp," :\n");
480 for (i=0; i<mffloat->n; i++) { spacer fprintf (fp," %d: \t%4.3f\n",i,mffloat->p[i]); }
481 break;
482 }
483 case FIELDTYPE_SFTime:
484 case FIELDTYPE_SFDouble:
485 {
486 double *sftime = (double*)value;
487 fprintf (fp," \t%4.3f\n",*sftime);
488 break;
489 }
490 case FIELDTYPE_MFTime:
491 case FIELDTYPE_MFDouble:
492 {
493 struct Multi_Double *mfdouble = (struct Multi_Double*)value;
494 fprintf (fp," :\n");
495 for (i=0; i<mfdouble->n; i++) { spacer fprintf (fp," %d: \t%4.3f\n",i,mfdouble->p[i]); }
496 break;
497 }
498 case FIELDTYPE_SFInt32:
499 case FIELDTYPE_SFBool:
500 {
501 int *sfint32 = (int*)(value);
502 fprintf (fp," \t%d\n",*sfint32);
503 break;
504 }
505 case FIELDTYPE_MFInt32:
506 case FIELDTYPE_MFBool:
507 {
508 struct Multi_Int32 *mfint32 = (struct Multi_Int32*)value;
509 fprintf (fp," :\n");
510 for (i=0; i<mfint32->n; i++) { spacer fprintf (fp," %d: \t%d\n",i,mfint32->p[i]); }
511 break;
512 }
513 case FIELDTYPE_SFVec2f:
514 {
515 struct SFVec2f * sfvec2f = (struct SFVec2f *)value;
516 fprintf (fp,": \t");
517 for (i=0; i<2; i++) { fprintf (fp,"%4.3f ",sfvec2f->c[i]); }
518 fprintf (fp,"\n");
519 break;
520 }
521 case FIELDTYPE_MFVec2f:
522 {
523 struct Multi_Vec2f *mfvec2f = (struct Multi_Vec2f*)value;
524 fprintf (fp," :\n");
525 for (i=0; i<mfvec2f->n; i++)
526 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f]\n",i,mfvec2f->p[i].c[0], mfvec2f->p[i].c[1]); }
527 break;
528 }
529 case FIELDTYPE_SFVec2d:
530 {
531 struct SFVec2d * sfvec2d = (struct SFVec2d *)value;
532 fprintf (fp,": \t");
533 for (i=0; i<2; i++) { fprintf (fp,"%4.3f ",sfvec2d->c[i]); }
534 fprintf (fp,"\n");
535 break;
536 }
537 case FIELDTYPE_MFVec2d:
538 {
539 struct Multi_Vec2d *mfvec2d = (struct Multi_Vec2d*)value;
540 fprintf (fp," :\n");
541 for (i=0; i<mfvec2d->n; i++)
542 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f]\n",i,mfvec2d->p[i].c[0], mfvec2d->p[i].c[1]); }
543 break;
544 }
545 case FIELDTYPE_SFVec3f:
546 case FIELDTYPE_SFColor:
547 {
548 struct SFVec3f * sfvec3f = (struct SFVec3f *)value;
549 fprintf (fp,": \t");
550 for (i=0; i<3; i++) { fprintf (fp,"%4.3f ",sfvec3f->c[i]); }
551 fprintf (fp,"\n");
552 break;
553 }
554 case FIELDTYPE_MFVec3f:
555 case FIELDTYPE_MFColor:
556 {
557 struct Multi_Vec3f *mfvec3f = (struct Multi_Vec3f*)value;
558 fprintf (fp," :\n");
559 for (i=0; i<mfvec3f->n; i++)
560 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f]\n",i,mfvec3f->p[i].c[0], mfvec3f->p[i].c[1],mfvec3f->p[i].c[2]); }
561 break;
562 }
563 case FIELDTYPE_SFVec3d:
564 {
565 struct SFVec3d * sfvec3d = (struct SFVec3d *)value;
566 fprintf (fp,": \t");
567 for (i=0; i<3; i++) { fprintf (fp,"%4.3f ",sfvec3d->c[i]); }
568 fprintf (fp,"\n");
569 break;
570 }
571 case FIELDTYPE_MFVec3d:
572 {
573 struct Multi_Vec3d *mfvec3d = (struct Multi_Vec3d*)value;
574 fprintf (fp," :\n");
575 for (i=0; i<mfvec3d->n; i++)
576 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f]\n",i,mfvec3d->p[i].c[0], mfvec3d->p[i].c[1],mfvec3d->p[i].c[2]); }
577 break;
578 }
579 case FIELDTYPE_SFVec4f:
580 case FIELDTYPE_SFColorRGBA:
581 case FIELDTYPE_SFRotation:
582 {
583 struct SFRotation * sfrot = (struct SFRotation *)value;
584 fprintf (fp,": \t");
585 for (i=0; i<4; i++) { fprintf (fp,"%4.3f ",sfrot->c[i]); }
586 fprintf (fp,"\n");
587 break;
588 }
589 case FIELDTYPE_MFVec4f:
590 case FIELDTYPE_MFColorRGBA:
591 case FIELDTYPE_MFRotation:
592 {
593 struct Multi_ColorRGBA *mfrgba = (struct Multi_ColorRGBA*)value;
594 fprintf (fp," :\n");
595 for (i=0; i<mfrgba->n; i++)
596 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f]\n",i,mfrgba->p[i].c[0], mfrgba->p[i].c[1],mfrgba->p[i].c[2],mfrgba->p[i].c[3]); }
597 break;
598 }
599 case FIELDTYPE_SFVec4d:
600 {
601 struct SFVec4d * sfvec4d = (struct SFVec4d *)value;
602 fprintf (fp,": \t");
603 for (i=0; i<4; i++) { fprintf (fp,"%4.3f ",sfvec4d->c[i]); }
604 fprintf (fp,"\n");
605 break;
606 }
607 case FIELDTYPE_MFVec4d:
608 {
609 struct Multi_Vec4d *mfvec4d = (struct Multi_Vec4d*)value;
610 fprintf (fp," :\n");
611 for (i=0; i<mfvec4d->n; i++)
612 { spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f]\n",i,mfvec4d->p[i].c[0], mfvec4d->p[i].c[1],mfvec4d->p[i].c[2],mfvec4d->p[i].c[3]); }
613 break;
614 }
615 case FIELDTYPE_SFMatrix3f:
616 {
617 struct SFMatrix3f *sfmat3f = (struct SFMatrix3f*)value;
618 spacer fprintf (fp," \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
619 sfmat3f->c[0],sfmat3f->c[1],sfmat3f->c[2],
620 sfmat3f->c[3],sfmat3f->c[4],sfmat3f->c[5],
621 sfmat3f->c[6],sfmat3f->c[7],sfmat3f->c[8]);
622 break;
623 }
624 case FIELDTYPE_MFMatrix3f:
625 {
626 struct Multi_Matrix3f *mfmat3f = (struct Multi_Matrix3f*)value;
627 fprintf (fp," :\n");
628 for (i=0; i<mfmat3f->n; i++) {
629 spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",i,
630 mfmat3f->p[i].c[0],mfmat3f->p[i].c[1],mfmat3f->p[i].c[2],
631 mfmat3f->p[i].c[3],mfmat3f->p[i].c[4],mfmat3f->p[i].c[5],
632 mfmat3f->p[i].c[6],mfmat3f->p[i].c[7],mfmat3f->p[i].c[8]); }
633 break;
634 }
635 case FIELDTYPE_SFMatrix3d:
636 {
637 struct SFMatrix3d *sfmat3d = (struct SFMatrix3d*)value;
638 spacer fprintf (fp," \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
639 sfmat3d->c[0],sfmat3d->c[1],sfmat3d->c[2],
640 sfmat3d->c[3],sfmat3d->c[4],sfmat3d->c[5],
641 sfmat3d->c[6],sfmat3d->c[7],sfmat3d->c[8]);
642 break;
643 }
644 case FIELDTYPE_MFMatrix3d:
645 {
646 struct Multi_Matrix3d *mfmat3d = (struct Multi_Matrix3d*)value;
647 fprintf (fp," :\n");
648 for (i=0; i<mfmat3d->n; i++) {
649 spacer fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",i,
650 mfmat3d->p[i].c[0],mfmat3d->p[i].c[1],mfmat3d->p[i].c[2],
651 mfmat3d->p[i].c[3],mfmat3d->p[i].c[4],mfmat3d->p[i].c[5],
652 mfmat3d->p[i].c[6],mfmat3d->p[i].c[7],mfmat3d->p[i].c[8]); }
653 break;
654 }
655 case FIELDTYPE_SFMatrix4f:
656 {
657 struct SFMatrix4f *sfmat4f = (struct SFMatrix4f*)value;
658 fprintf (fp," \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
659 sfmat4f->c[0],sfmat4f->c[1],sfmat4f->c[2],sfmat4f->c[3],
660 sfmat4f->c[4],sfmat4f->c[5],sfmat4f->c[6],sfmat4f->c[7],
661 sfmat4f->c[8],sfmat4f->c[9],sfmat4f->c[10],sfmat4f->c[11],
662 sfmat4f->c[12],sfmat4f->c[13],sfmat4f->c[14],sfmat4f->c[15]);
663 break;
664 }
665 case FIELDTYPE_MFMatrix4f:
666 {
667 struct Multi_Matrix4f *mfmat4f = (struct Multi_Matrix4f*)value;
668 fprintf (fp," :\n");
669 for (i=0; i<mfmat4f->n; i++) {
670 spacer
671 fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",i,
672 mfmat4f->p[i].c[0],mfmat4f->p[i].c[1],mfmat4f->p[i].c[2],mfmat4f->p[i].c[3],
673 mfmat4f->p[i].c[4],mfmat4f->p[i].c[5],mfmat4f->p[i].c[6],mfmat4f->p[i].c[7],
674 mfmat4f->p[i].c[8],mfmat4f->p[i].c[9],mfmat4f->p[i].c[10],mfmat4f->p[i].c[11],
675 mfmat4f->p[i].c[12],mfmat4f->p[i].c[13],mfmat4f->p[i].c[14],mfmat4f->p[i].c[15]); }
676 break;
677 }
678 case FIELDTYPE_SFMatrix4d:
679 {
680 struct SFMatrix4d *sfmat4d = (struct SFMatrix4d*)value;
681 fprintf (fp," \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",
682 sfmat4d->c[0],sfmat4d->c[1],sfmat4d->c[2],sfmat4d->c[3],
683 sfmat4d->c[4],sfmat4d->c[5],sfmat4d->c[6],sfmat4d->c[7],
684 sfmat4d->c[8],sfmat4d->c[9],sfmat4d->c[10],sfmat4d->c[11],
685 sfmat4d->c[12],sfmat4d->c[13],sfmat4d->c[14],sfmat4d->c[15]);
686 break;
687 }
688 case FIELDTYPE_MFMatrix4d:
689 {
690 struct Multi_Matrix4d *mfmat4d = (struct Multi_Matrix4d*)value;
691 fprintf (fp," :\n");
692 for (i=0; i<mfmat4d->n; i++) {
693 spacer
694 fprintf (fp," %d: \t[%4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f, %4.3f ]\n",i,
695 mfmat4d->p[i].c[0],mfmat4d->p[i].c[1],mfmat4d->p[i].c[2],mfmat4d->p[i].c[3],
696 mfmat4d->p[i].c[4],mfmat4d->p[i].c[5],mfmat4d->p[i].c[6],mfmat4d->p[i].c[7],
697 mfmat4d->p[i].c[8],mfmat4d->p[i].c[9],mfmat4d->p[i].c[10],mfmat4d->p[i].c[11],
698 mfmat4d->p[i].c[12],mfmat4d->p[i].c[13],mfmat4d->p[i].c[14],mfmat4d->p[i].c[15]); }
699 break;
700 }
701
702 case FIELDTYPE_SFImage:
703 {
704 fprintf(fp," %p \n",(void *)value); //no SFImage struct defined
705 break;
706 }
707 }
708} //return print_field
709
710/*
711dump_scene2() is like dump_scene() - a way to printf all the nodes and their fields,
712when you hit a key on the keyboard ie '|'
713and recurse if a field is an SFNode or MFNode, tabbing in and out to show the recursion level
714- except dump_scene2 iterates over fields in a generic way to get all fields
715- could be used as an example for deep copying binary nodes
716- shows script/user fields and built-in fields
717*/
718void dump_scene2(FILE *fp, int level, struct X3D_Node* node, int recurse, Stack *DEFedNodes) {
719 #define spacer for (lc=0; lc<level; lc++) fprintf (fp," ");
720 int lc;
721 int isDefed;
722 char *nodeName;
723 //(int) FIELDNAMES_children, (int) offsetof (struct X3D_Group, children), (int) FIELDTYPE_MFNode, (int) KW_inputOutput, (int) (SPEC_VRML | SPEC_X3D30 | SPEC_X3D31 | SPEC_X3D32 | SPEC_X3D33),
724 //typedef struct field_info{
725 // int nameIndex;
726 // int offset;
727 // int typeIndex;
728 // int ioType;
729 // int version;
730 // int unca;
731 //} *finfo;
732 fieldinfo offsets;
733 fieldinfo field;
734 int ifield;
735
736 #ifdef FW_DEBUG
737 Boolean allFields;
738 if (fileno(fp) == fileno(stdout)) { allFields = TRUE; } else { allFields = FALSE; }
739 #else
740 Boolean allFields = TRUE; //FALSE;
741 #endif
742 /* See vi +/double_conditional codegen/VRMLC.pm */
743 if (node==NULL) return;
744
745 fflush(fp);
746 if (level == 0) fprintf (fp,"starting dump_scene2\n");
747 nodeName = parser_getNameFromNode(node) ;
748 isDefed = isNodeDEFedYet(node,DEFedNodes);
749 spacer fprintf (fp,"L%d: node (%p) (",level,node);
750 if(nodeName != NULL) {
751 if(isDefed)
752 fprintf(fp,"USE %s",nodeName);
753 else
754 fprintf(fp,"DEF %s",nodeName);
755 }
756 fprintf(fp,") type %s\n",stringNodeType(node->_nodeType));
757 //fprintf(fp,"recurse=%d ",recurse);
758 if(recurse && !isDefed)
759 {
760 vector_pushBack(struct X3D_Node*, DEFedNodes, node);
761 offsets = (fieldinfo)NODE_OFFSETS[node->_nodeType];
762 ifield = 0;
763 field = &offsets[ifield];
764 while( field->nameIndex > -1) //<< generalized for scripts and builtins?
765 {
766 int privat;
767 privat = FIELDNAMES[field->nameIndex][0] == '_';
768 privat = privat && strcmp(FIELDNAMES[field->nameIndex],"__scriptObj");
769 privat = privat && strcmp(FIELDNAMES[field->nameIndex],"__protoDef");
770 if(allFields || !privat)
771 {
772 spacer
773 fprintf(fp," %s",FIELDNAMES[field->nameIndex]); //[0]]);
774 fprintf(fp," (%s)",FIELDTYPES[field->typeIndex]); //field[2]]);
775 if(node->_nodeType == NODE_Script && !strcmp(FIELDNAMES[field->nameIndex],"__scriptObj") )
776 {
777 int k;
778 struct Vector *sfields;
779 struct ScriptFieldDecl *sfield;
780 struct FieldDecl *fdecl;
781 struct Shader_Script *sp;
782 struct CRjsnameStruct *JSparamnames = getJSparamnames();
783
784 sp = *(struct Shader_Script **)&((char*)node)[field->offset];
785 fprintf(fp,"loaded = %d\n",sp->loaded);
786 sfields = sp->fields;
787 //fprintf(fp,"sp->fields->n = %d\n",sp->fields->n);
788 for(k=0;k<sfields->n;k++)
789 {
790 char *fieldName;
791 sfield = vector_get(struct ScriptFieldDecl *,sfields,k);
792 //if(sfield->ASCIIvalue) printf("Ascii value=%s\n",sfield->ASCIIvalue);
793 fdecl = sfield->fieldDecl;
794 fieldName = fieldDecl_getShaderScriptName(fdecl);
795 fprintf(fp," %s",fieldName);
796 //fprintf(fp," (%s)",FIELDTYPES[field->typeIndex]); //field[2]]);
797 fprintf(fp," (%s)", stringFieldtypeType(fdecl->fieldType)); //fdecl->fieldType)
798 fprintf(fp," %s ",stringPROTOKeywordType(fdecl->PKWmode));
799
800 if(fdecl->PKWmode == PKW_initializeOnly)
801 print_field(fp,level,fdecl->fieldType,fieldName,&(sfield->value),DEFedNodes);
802 else
803 fprintf(fp,"\n");
804 }
805 level--;
806 }
807 else if(node->_nodeType == NODE_Proto && !strcmp(FIELDNAMES[field->nameIndex],"__protoDef") )
808 {
809 int k; //, mode;
810 struct ProtoFieldDecl* pfield;
811 struct X3D_Proto* pnode = (struct X3D_Proto*)node;
812 struct ProtoDefinition* pstruct = (struct ProtoDefinition*) pnode->__protoDef;
813 if(pstruct){
814 fprintf(fp," user fields:\n");
815 level++;
816 if(pstruct->iface)
817 for(k=0; k!=vectorSize(pstruct->iface); ++k)
818 {
819 const char *fieldName;
820 pfield= vector_get(struct ProtoFieldDecl*, pstruct->iface, k);
821 //mode = pfield->mode;
822 fieldName = pfield->cname;
823 spacer
824 fprintf(fp," %p ",(void*)pfield);
825 fprintf(fp," %s",fieldName);
826 fprintf(fp," (%s)", stringFieldtypeType(pfield->type)); //fdecl->fieldType)
827 fprintf(fp," %s ",stringPROTOKeywordType(pfield->mode));
828
829 if(pfield->mode == PKW_initializeOnly || pfield->mode == PKW_inputOutput)
830 print_field(fp,level,pfield->type,fieldName,&(pfield->defaultVal),DEFedNodes);
831 else
832 fprintf(fp,"\n");
833 }
834 level--;
835 }
836 }else{
837 union anyVrml* any_except_PTR = (union anyVrml*)&((char*)node)[field->offset];
838 print_field(fp,level,field->typeIndex,FIELDNAMES[field->nameIndex],any_except_PTR,DEFedNodes);
839 }
840 }
841 ifield++;
842 field = &offsets[ifield];
843 }
844 }
845 fflush(fp) ;
846 spacer fprintf (fp,"L%d end\n",level);
847 if (level == 0) fprintf (fp,"ending dump_scene2\n");
848}
849
850/* deep_copy2() - experimental keyboard reachable deepcopy function */
851void deep_copy2(int iopt, char* defname)
852{
853 struct X3D_Node* node;
854 char *name2;
855 node = NULL;
856 ConsoleMessage("in deep_copy2 - for copying a node and its fields\n");
857 ConsoleMessage("got iopt=%d defname=%s\n",iopt,defname);
858 if(iopt == 0) return;
859 if(iopt == 1)
860 {
861 node = parser_getNodeFromName(defname);
862 }
863 if(iopt == 2)
864 {
865 node = (struct X3D_Node*)rootNode();
866 }
867 if(iopt == 3)
868 {
869 sscanf(defname,"%p",&node);
870 }
871 if( checkNode(node, NULL, 0) )
872 {
873 name2 = parser_getNameFromNode(node);
874 if(name2 != NULL)
875 ConsoleMessage("You entered %s\n",name2);
876 else
877 ConsoleMessage("Node exists!\n");
878 }else{
879 ConsoleMessage("Node does not exist.\n");
880 }
881}
882
883void print_DEFed_node_names_and_pointers(FILE* fp)
884{
885 int ind,j,jj,nstack,nvector;
886 char * name;
887 struct X3D_Node * node;
888 struct Vector *curNameStackTop;
889 struct Vector *curNodeStackTop;
890 struct VRMLParser *globalParser = (struct VRMLParser *)gglobal()->CParse.globalParser;
891
892 fprintf(fp,"DEFedNodes ");
893 if(!globalParser) return;
894 if(globalParser->DEFedNodes == NULL)
895 {
896 fprintf(fp," NULL\n");
897 return;
898 }
899 nstack = globalParser->lexer->userNodeNames->n;
900 fprintf(fp," lexer namespace vectors = %d\n",nstack);
901 for(j=0;j<nstack;j++)
902 {
903 curNameStackTop = vector_get(struct Vector *, globalParser->lexer->userNodeNames,j);
904 curNodeStackTop = vector_get(struct Vector *, globalParser->DEFedNodes,j);
905 if(curNameStackTop && curNodeStackTop)
906 {
907 nvector = vectorSize(curNodeStackTop);
908 for(jj=0;jj<j;jj++) fprintf(fp," ");
909 fprintf(fp,"vector %d name count = %d\n",j,nvector);
910 for (ind=0; ind < nvector; ind++)
911 {
912 for(jj=0;jj<j;jj++) fprintf(fp," ");
913 node = vector_get(struct X3D_Node*,curNodeStackTop, ind);
914 name = vector_get(char *,curNameStackTop, ind);
915 fprintf (fp,"L%d: node (%p) name (%s) \n",jj,node,name);
916 }
917 }
918 }
919}
920char *findFIELDNAMESfromNodeOffset0(struct X3D_Node *node, int offset)
921{
922 if( node->_nodeType != NODE_Script)
923 {
924 if( node->_nodeType == NODE_Proto )
925 {
926 //int mode;
927 struct ProtoFieldDecl* pfield;
928 struct X3D_Proto* pnode = (struct X3D_Proto*)node;
929 struct ProtoDefinition* pstruct = (struct ProtoDefinition*) pnode->__protoDef;
930 if(pstruct){
931 if(pstruct->iface) {
932 if(offset < vectorSize(pstruct->iface))
933 {
934 //JAS const char *fieldName;
935 pfield= vector_get(struct ProtoFieldDecl*, pstruct->iface, offset);
936 //mode = pfield->mode;
937 return pfield->cname;
938 } else return NULL;
939 }
940 }else return NULL;
941 }
942 else
943 //return (char *)FIELDNAMES[NODE_OFFSETS[node->_nodeType][offset*5]];
944 return (char *)findFIELDNAMESfromNodeOffset(node,offset);
945 }
946
947 {
948 struct Vector* fields;
949 struct ScriptFieldDecl* curField;
950
951 struct Shader_Script *myObj = X3D_SCRIPT(node)->__scriptObj;
952 struct CRjsnameStruct *JSparamnames = getJSparamnames();
953
954 fields = myObj->fields;
955 curField = vector_get(struct ScriptFieldDecl*, fields, offset);
956 return fieldDecl_getShaderScriptName(curField->fieldDecl);
957 }
958
959}
960char *findFIELDNAMES0(struct X3D_Node *node, int offset)
961{
962 return findFIELDNAMESfromNodeOffset0(node,offset);
963}
964#include "../vrml_parser/CRoutes.h"
965void print_routes_ready_to_register(FILE* fp);
966void print_routes(FILE* fp)
967{
968 int numRoutes;
969 int count;
970 struct X3D_Node *fromNode;
971 struct X3D_Node *toNode;
972 int fromOffset;
973 int toOffset;
974 char *fromName;
975 char *toName;
976
977 print_routes_ready_to_register(fp);
978 numRoutes = getRoutesCount();
979 fprintf(fp,"Number of Routes %d\n",numRoutes-2);
980 if (numRoutes < 2) {
981 return;
982 }
983
984 /* remember, in the routing table, the first and last entres are invalid, so skip them */
985 for (count = 1; count < (numRoutes-1); count++) {
986 getSpecificRoute (count,&fromNode, &fromOffset, &toNode, &toOffset);
987 fromName = parser_getNameFromNode(fromNode);
988 toName = parser_getNameFromNode(toNode);
989
990 fprintf (fp, " %p %s.%s TO %p %s.%s \n",fromNode,fromName,
991 findFIELDNAMESfromNodeOffset0(fromNode,fromOffset),
992 toNode,toName,
993 findFIELDNAMESfromNodeOffset0(toNode,toOffset)
994 );
995 }
996}
997static struct consoleMenuState
998{
999 int active;
1000 void (*f)(void*,char*);
1001 char buf[100];
1002 int len;
1003 char *dfault;
1004 void *yourData;
1005} ConsoleMenuState;
1006int consoleMenuActive()
1007{
1008 return ConsoleMenuState.active;
1009}
1010void setConsoleMenu(void *yourData, char *prompt, void (*callback), char* dfault)
1011{
1012 ConsoleMenuState.f = callback;
1013 ConsoleMenuState.len = 0;
1014 ConsoleMenuState.buf[0] = '\0';
1015 ConsoleMenuState.active = TRUE;
1016 ConsoleMenuState.dfault = dfault;
1017 ConsoleMenuState.yourData = yourData;
1018 ConsoleMessage(prompt);
1019 ConsoleMessage("[%s]:",dfault);
1020}
1021void deep_copy_defname(void *myData, char *defname)
1022{
1023 int iopt;
1024 ConsoleMessage("you entered defname: %s\n",defname);
1025 memcpy(&iopt,myData,4);
1026 deep_copy2(iopt,defname);
1027 FREE(myData);
1028}
1029void deep_copy_option(void* yourData, char *opt)
1030{
1031 int iopt;
1032 ConsoleMessage("you chose option %s\n",opt);
1033 sscanf(opt,"%d",&iopt);
1034 if(iopt == 0) return;
1035 if(iopt == 1 || iopt == 3)
1036 {
1037 void* myData = MALLOC(void *, 4); //could store in gglobal->mainloop or wherever, then don't free in deep_copy_defname
1038 memcpy(myData,&iopt,4);
1039 setConsoleMenu(myData,"Enter DEFname or node address:", deep_copy_defname, "");
1040 }
1041 if(iopt == 2)
1042 deep_copy2(iopt, NULL);
1043}
1044void dump_scenegraph(int method)
1045{
1046//#ifdef FW_DEBUG
1047 if(method == 1) // '\\'
1048 dump_scene(stdout, 0, (struct X3D_Node*) rootNode());
1049 else if(method == 2) // '|'
1050 {
1051 Stack * DEFedNodes = newVector(struct X3D_Node*, 2);
1052 dump_scene2(stdout, 0, (struct X3D_Node*) rootNode(),1,DEFedNodes);
1053 deleteVector(struct X3D_Node*,DEFedNodes);
1054 }
1055 else if(method == 3) // '='
1056 {
1057 print_DEFed_node_names_and_pointers(stdout);
1058 }
1059 else if(method == 4) // '+'
1060 {
1061 print_routes(stdout);
1062 }
1063 else if(method == 5) // '-'
1064 {
1065 //ConsoleMenuState.active = 1; //deep_copy2();
1066 setConsoleMenu(NULL,"0. Exit 1.DEFname 2.ROOTNODE 3.node address", deep_copy_option, "0");
1067 }
1068//#endif
1069}
1070
1071//Mar 2016 added to all nodes void* _gc field to hold an optional vector of malloc pointers
1072//for freeing at end of program.
1073void register_node_gc(void *node, void *p);
1074void unregister_node_gc(void *node, void *p); //unregister old on realloc
1075void free_registered_node_gc(void* node); //free when freeing node ie freeMallocedNodeFields
1076
1077void register_node_gc(void *node, void *p){
1078 struct X3D_Node* _node = (struct X3D_Node*)node;
1079 if(!_node->_gc) _node->_gc = newVector(void*,1);
1080 vector_pushBack(void*,_node->_gc,p);
1081}
1082void unregister_node_gc(void *node, void *p){
1083 int i;
1084 struct Vector *v;
1085 void *p0;
1086 struct X3D_Node* _node = (struct X3D_Node*)node;
1087
1088 if(!_node->_gc) return;
1089 if(!p) return;
1090 v = (struct Vector*)_node->_gc;
1091 for(i=0;i<v->n;i++){
1092 p0 = vector_get(void*,v,i);
1093 if(p0 == p){
1094 vector_set(void*,v,i,NULL);
1095 break;
1096 }
1097 }
1098}
1099void free_registered_node_gc(void* node){
1100 struct X3D_Node* _node = (struct X3D_Node*)node;
1101 if(_node->_gc){
1102 int i;
1103 void *p;
1104 struct Vector *v = (struct Vector *)_node->_gc;
1105 for(i=0;i<v->n;i++){
1106 p = vector_get(void *,v,i);
1107 FREE_IF_NZ(p);
1108 }
1109 deleteVector(void*,_node->_gc);
1110 }
1111}
1112
1113
1114
1115
1116
1117#if defined(DISABLER) || defined(DISABLER_MALLOC)
1118// ================ nice new code by disabler. use while tg still alive===============
1119#ifdef _ANDROID
1120#define WRAP_MALLOC 1
1121
1122#ifdef DEBUG
1123int DROIDDEBUG( const char*pFmtStr, ...);
1124#define printf DROIDDEBUG
1125#endif
1126
1127#endif
1128
1133#if defined(WRAP_MALLOC) || defined(DEBUG_MALLOC)
1134
1135#define FWL_NOT_FOUND_IN_MEM_TABLE -1
1136
1137void __free_memtable_elem(void *ptr);
1138void __free_memtable_elem_with_data(void *ptr);
1139int __match_memtable_elem(void *elem1, void *elem2);
1140
1141typedef struct fwl_memtable_elem
1142{
1143 void *ptr;
1144 int lineNubmer;
1145 char *fileName;
1146} fwl_memtable_elem;
1147
1148
1149static ttglobal sLastSeenGlobal = NULL;
1150
1151void __freeWholeMemTable(ttglobal gg)
1152{
1153 if (gg->__memTable != NULL)
1154 {
1155 gg->__memTable->free = &__free_memtable_elem_with_data;
1156 dbl_list_destroy(gg->__memTable);
1157 gg->__memTable = NULL;
1158 }
1159}
1160
1161int __removeFromMemTable(ttglobal gg, void *ptr, char *file, int line)
1162{
1163 int retVal = FWL_NOT_FOUND_IN_MEM_TABLE;
1164 if (gg->__memTable != NULL)
1165 {
1166 fwl_memtable_elem searchedElem;
1167 searchedElem.ptr = ptr;
1168 dbl_list_node_t *node = dbl_list_find(gg->__memTable, &searchedElem);
1169 if (node)
1170 {
1171 retVal = 0;
1172 dbl_list_remove(gg->__memTable, node);
1173 }
1174 else
1175 {
1176 printf ("freewrlFree - did not find 0x%016llx at %s:%d\n", (unsigned long long)ptr,file,line);
1177 }
1178 }
1179
1180 return retVal;
1181}
1182
1183void __reserveInMemTable(ttglobal gg, void *ptr, char *file, int line)
1184{
1185 if (gg->__memTable != NULL)
1186 {
1187 fwl_memtable_elem searchedElem;
1188 searchedElem.ptr = ptr;
1189 dbl_list_node_t *node = dbl_list_find(gg->__memTable, &searchedElem);
1190 if (node)
1191 {
1192 fwl_memtable_elem *foundElem = (fwl_memtable_elem *)node->val;
1193
1194 printf ("freewrl__ReserveInMemTable - ptr already in the table 0x%016llx at %s:%d, added at %s:%d\n", (unsigned long long)ptr, file, line, foundElem->fileName, foundElem->lineNubmer);
1195
1196 }
1197 else
1198 {
1199 fwl_memtable_elem *newElem = malloc(sizeof(fwl_memtable_elem));
1200 newElem->fileName = file;
1201 newElem->lineNubmer = line;
1202 newElem->ptr = ptr;
1203 dbl_list_rpush(gg->__memTable, dbl_list_node_new(newElem));
1204 }
1205 }
1206}
1207
1208#define LOCK_GLOBAL_MEMORYTABLE if (tg) pthread_mutex_lock(&tg->__memTableGlobalLock);
1209#define UNLOCK_GLOBAL_MEMORYTABLE if (tg) pthread_mutex_unlock(&tg->__memTableGlobalLock);
1210
1211ttglobal freewrlGetActualGlobal()
1212{
1213 ttglobal tg = gglobal0();
1214 if (tg)
1215 {
1216 sLastSeenGlobal = tg;
1217 }
1218 else
1219 {
1220 tg = sLastSeenGlobal;
1221 }
1222
1223 return tg;
1224}
1225
1226void freewrlInitMemTable()
1227{
1228 ttglobal tg = freewrlGetActualGlobal();
1229 if (tg)
1230 {
1231 pthread_mutex_init(&(tg->__memTableGlobalLock), NULL);
1232 }
1233 LOCK_GLOBAL_MEMORYTABLE
1234
1235 if (tg && !tg->__memTable_CheckInit) {
1236
1237 tg->__memTable = dbl_list_new();
1238 tg->__memTable->free = &__free_memtable_elem;
1239 tg->__memTable->match = &__match_memtable_elem;
1240 tg->__memTable_CheckInit = TRUE;
1241 }
1242
1243 UNLOCK_GLOBAL_MEMORYTABLE
1244}
1245
1246void __free_memtable_elem_with_data(void *ptr)
1247{
1248 fwl_memtable_elem *elem = (fwl_memtable_elem *)ptr;
1249 #ifdef DEBUG_MALLOC
1250 printf ("freewrl MemTable disposing ptr 0x%016llx\n", (unsigned long long)elem->ptr);
1251 #endif
1252 free(elem->ptr);
1253 free(elem);
1254}
1255
1256void __free_memtable_elem(void *ptr)
1257{
1258 free(ptr);
1259}
1260
1261int __match_memtable_elem(void *elem1, void *elem2)
1262{
1263 return ((fwl_memtable_elem *)elem1)->ptr == ((fwl_memtable_elem *)elem2)->ptr;
1264}
1265
1266void freewrlDisposeMemTable()
1267{
1268 ttglobal tg = freewrlGetActualGlobal();
1269 if (tg)
1270 {
1271 pthread_mutex_destroy(&(tg->__memTableGlobalLock));
1272 if (sLastSeenGlobal == tg)
1273 {
1274 sLastSeenGlobal = NULL;
1275 }
1276 }
1277}
1278
1279void freewrlFree(int line, char *file, void *a)
1280{
1281 ttglobal tg = freewrlGetActualGlobal();
1282 LOCK_GLOBAL_MEMORYTABLE
1283 if (tg)
1284 {
1285 #ifdef DEBUG_MALLOC
1286 printf ("freewrlFree 0x%016llx xfree at %s:%d\n", (unsigned long long)a, file,line);
1287 #endif
1288
1289 __removeFromMemTable(tg, a,file,line);
1290 }
1291
1292 UNLOCK_GLOBAL_MEMORYTABLE
1293 free(a);
1294}
1295
1296void scanMallocTableOnQuit()
1297{
1298 ttglobal tg = freewrlGetActualGlobal();
1299 LOCK_GLOBAL_MEMORYTABLE
1300 if (tg)
1301 {
1302 dbl_list_iterator_t *it = dbl_list_iterator_new(tg->__memTable, LIST_HEAD);
1303 dbl_list_node_t *node;
1304 while ((node = dbl_list_iterator_next(it))) {
1305 fwl_memtable_elem *elem = ((fwl_memtable_elem *)node->val);
1306 printf ("unfreed memory %016llx created at %s:%d \n", (unsigned long long)elem->ptr, elem->fileName, elem->lineNubmer);
1307 }
1308 dbl_list_iterator_destroy(it);
1309 }
1310 UNLOCK_GLOBAL_MEMORYTABLE
1311}
1312
1313void freewrlSetShouldRegisterAllocation(bool shouldRegisterAllocation)
1314{
1315 ttglobal tg = freewrlGetActualGlobal();
1316 LOCK_GLOBAL_MEMORYTABLE
1317 if (tg)
1318 {
1319 tg->__memTable_ShouldRegisterAllocation = shouldRegisterAllocation;
1320 }
1321 UNLOCK_GLOBAL_MEMORYTABLE
1322}
1323
1324bool freewrlIsRegisteringAllocation()
1325{
1326 ttglobal tg = freewrlGetActualGlobal();
1327
1328 if (tg)
1329 {
1330 return tg->__memTable_ShouldRegisterAllocation;
1331 }
1332
1333 return FALSE;
1334}
1335
1336void freewrlFreeAllRegisteredAllocations()
1337{
1338 ttglobal tg = freewrlGetActualGlobal();
1339 LOCK_GLOBAL_MEMORYTABLE
1340 if (tg)
1341 {
1342 __freeWholeMemTable(tg);
1343 }
1344 UNLOCK_GLOBAL_MEMORYTABLE
1345}
1346
1350void *freewrlMalloc(int line, char *file, size_t sz, int zeroData)
1351{
1352 void *rv;
1353
1354 ttglobal tg = freewrlGetActualGlobal();
1355 LOCK_GLOBAL_MEMORYTABLE
1356
1357 rv = malloc(sz);
1358 if (zeroData) bzero (rv, sz);
1359
1360 #ifdef DEBUG_MALLOC
1361 if (rv == NULL)
1362 {
1363 char myline[400];
1364 sprintf (myline, "MALLOC PROBLEM - out of memory at %s:%d for %zu",file,line,sz);
1365 outOfMemory (myline);
1366 }
1367
1368 printf ("freewrlMalloc 0x%016llx size %zu at %s:%d\n", (unsigned long long)rv,sz,file,line);
1369 #endif
1370
1371 if (tg && tg->__memTable_ShouldRegisterAllocation)
1372 {
1373 __reserveInMemTable(tg, rv,file,line);
1374 }
1375
1376 UNLOCK_GLOBAL_MEMORYTABLE
1377
1378 return rv;
1379}
1380
1381void *freewrlRealloc(int line, char *file, void *ptr, size_t size)
1382{
1383 void *rv;
1384
1385 ttglobal tg = freewrlGetActualGlobal();
1386 LOCK_GLOBAL_MEMORYTABLE
1387
1388// printf ("%016llx xfree (from realloc) at %s:%d\n",ptr,file,line);
1389 rv = realloc (ptr,size);
1390
1391 #ifdef DEBUG_MALLOC
1392 if (rv == NULL)
1393 {
1394 if (size != 0)
1395 {
1396 char myline[400];
1397 sprintf (myline, "REALLOC PROBLEM - out of memory at %s:%d size %zu",file,line,size);
1398 outOfMemory (myline);
1399 }
1400 }
1401
1402 printf ("freewrlRealloc 0x%016llx to 0x%016llx size %zu at %s:%d\n", (unsigned long long)ptr, (unsigned long long)rv, size, file, line);
1403 #endif
1404
1405 if (tg)
1406 {
1407 int result = 0;
1408 if (NULL != ptr)
1409 {
1410 result = __removeFromMemTable(tg, ptr,file,line);
1411 }
1412 if (result != FWL_NOT_FOUND_IN_MEM_TABLE) // If we were tracking this ptr previously
1413 {
1414 if (tg->__memTable_ShouldRegisterAllocation)
1415 {
1416 __reserveInMemTable(tg, rv,file,line);
1417 }
1418 }
1419 else
1420 {
1421 printf ("0x%016llx FOR REALLOC NOT FOUND for size %zu at %s:%d\n", (unsigned long long)ptr,size,file,line);
1422 }
1423 }
1424
1425 UNLOCK_GLOBAL_MEMORYTABLE
1426 return rv;
1427}
1428
1429
1430void *freewrlStrdup (int line, char *file, const char *str)
1431{
1432 void *rv;
1433
1434 ttglobal tg = freewrlGetActualGlobal();
1435 LOCK_GLOBAL_MEMORYTABLE
1436 rv = strdup (str);
1437
1438 #ifdef DEBUG_MALLOC
1439 printf("freewrlStrdup 0x%016llx, at line %d file %s\n",(unsigned long long)rv, line,file);
1440 if (rv == NULL)
1441 {
1442 char myline[400];
1443 sprintf (myline, "STRDUP PROBLEM - out of memory at %s:%d ",file,line);
1444 outOfMemory (myline);
1445 }
1446 #endif
1447
1448 if (tg && tg->__memTable_ShouldRegisterAllocation)
1449 {
1450 __reserveInMemTable(tg, rv,file,line);
1451 }
1452 UNLOCK_GLOBAL_MEMORYTABLE
1453 return rv;
1454}
1455
1456void *freewrlStrndup (int line, char *file, const char *str, size_t n)
1457{
1458 void *rv;
1459 ttglobal tg = freewrlGetActualGlobal();
1460 LOCK_GLOBAL_MEMORYTABLE
1461
1462 rv = strndup (str, n);
1463
1464 #ifdef DEBUG_MALLOC
1465 printf("freewrlStrndup 0x%016llx count at line %d file %s\n", (unsigned long long)rv, line,file);
1466 if (rv == NULL)
1467 {
1468 char myline[400];
1469 sprintf (myline, "STRNDUP PROBLEM - out of memory at %s:%d ",file,line);
1470 outOfMemory (myline);
1471 }
1472 #endif
1473
1474 if (tg && tg->__memTable_ShouldRegisterAllocation)
1475 {
1476 __reserveInMemTable(tg, rv,file,line);
1477 }
1478 UNLOCK_GLOBAL_MEMORYTABLE
1479 return rv;
1480}
1481
1482#endif /* defined(WRAP_MALLOC) || defined(DEBUG_MALLOC) */
1483
1489#endif
1490
1491//================ older code hacked by dug9, can work after tg disposed================
1492#ifndef DISABLER
1493
1497// OLDCODE pthread_mutex_t __memTableGlobalLock = PTHREAD_MUTEX_INITIALIZER;
1498// OLDCODE #define LOCK_GLOBAL_MEMORYTABLE pthread_mutex_lock(&__memTableGlobalLock);
1499// OLDCODE #define UNLOCK_GLOBAL_MEMORYTABLE pthread_mutex_unlock(&__memTableGlobalLock);
1500
1501#ifdef DEBUG_MALLOC
1502static int _noisy = 0; //=1 if more printfs during malloc and free, 0 if just summary on exit
1503
1504#define MAXMALLOCSTOKEEP 100000
1505static int mcheckinit = FALSE;
1506static void* mcheck[MAXMALLOCSTOKEEP];
1507static char* mplace[MAXMALLOCSTOKEEP];
1508static int mlineno[MAXMALLOCSTOKEEP];
1509static size_t msize[MAXMALLOCSTOKEEP];
1510static int mcount;
1511
1512static mcheck_init(){
1513 if (!mcheckinit) {
1514 for (mcount=0; mcount < MAXMALLOCSTOKEEP; mcount++) {
1515 mcheck[mcount] = NULL;
1516 mplace[mcount] = NULL;
1517 mlineno[mcount] = 0;
1518 }
1519 mcheckinit = TRUE;
1520 }
1521
1522}
1523
1524void FREETABLE(void *a,char *file,int line) {
1525 LOCK_GLOBAL_MEMORYTABLE
1526 mcount=0;
1527 while ((mcount<(MAXMALLOCSTOKEEP-1)) && (mcheck[mcount]!=a)) mcount++;
1528 if (mcheck[mcount]!=a) {
1529 printf ("freewrlFree - did not find %p at %s:%d\n",a,file,line);
1530 printf("mcount = %d\n",mcount);
1531 } else {
1532 /* printf ("found %d in mcheck table\n"); */
1533 //if(mlineno[mcount]==1798 || mlineno[mcount]==1803)
1534 // printf("gotcha\n");
1535 mcheck[mcount] = NULL;
1536 mlineno[mcount] = 0;
1537 if (mplace[mcount]!=NULL) free(mplace[mcount]);
1538 mplace[mcount]=NULL;
1539 }
1540 UNLOCK_GLOBAL_MEMORYTABLE
1541}
1542
1543void RESERVETABLE(void *a, char *file,int line,int size) {
1544 LOCK_GLOBAL_MEMORYTABLE
1545 mcount=0;
1546 while ((mcount<(MAXMALLOCSTOKEEP-1)) && (mcheck[mcount]!=NULL)) mcount++;
1547 if (mcheck[mcount]!=NULL) {
1548 printf ("freewrlMalloc - out of malloc check store\n");
1549 printf("mcount=%d\n",mcount);
1550 printf("a=%p\n",a);
1551 } else {
1552 mcheck[mcount] = a;
1553 mlineno[mcount] = line;
1554 mplace[mcount] = strdup(file);
1555 msize[mcount] = size;
1556 }
1557 UNLOCK_GLOBAL_MEMORYTABLE
1558}
1559
1560void freewrlFree(int line, char *file, void *a)
1561{
1562 mcheck_init();
1563 if(_noisy) printf ("freewrlFree %p xfree at %s:%d\n",a,file,line);
1564 if(a)
1565 FREETABLE(a,file,line);
1566 free(a);
1567}
1568
1569void scanMallocTableOnQuit_old()
1570{
1571 for (mcount=0; mcount<MAXMALLOCSTOKEEP;mcount++) {
1572 if (mcheck[mcount]!=NULL) {
1573 printf ("unfreed memory %p created at %s:%d \n",mcheck[mcount], mplace[mcount],mlineno[mcount]);
1574 }
1575 }
1576}
1577typedef struct malloc_location {
1578 int count;
1579 int line;
1580 size_t size;
1581 char *fname;
1582} malloc_location;
1583#include <memory.h>
1584#ifdef _MSC_VER
1585#define alloca _alloca
1586#endif
1587int comp_count (const void * elem1, const void * elem2)
1588{
1589 malloc_location *e1, *e2;
1590 e1 = (malloc_location*)elem1;
1591 e2 = (malloc_location*)elem2;
1592 return e1->count < e2->count ? -1 : e1->count > e2->count ? 1 : 0;
1593}
1594int comp_size (const void * elem1, const void * elem2)
1595{
1596 malloc_location *e1, *e2;
1597 e1 = (malloc_location*)elem1;
1598 e2 = (malloc_location*)elem2;
1599 return e1->size < e2->size ? -1 : e1->size > e2->size ? 1 : 0;
1600}
1601int comp_file (const void * elem1, const void * elem2)
1602{
1603 malloc_location *e1, *e2;
1604 e1 = (malloc_location*)elem1;
1605 e2 = (malloc_location*)elem2;
1606 return strcmp(e1->fname,e2->fname);
1607}
1608int comp_line (const void * elem1, const void * elem2)
1609{
1610 malloc_location *e1, *e2;
1611 e1 = (malloc_location*)elem1;
1612 e2 = (malloc_location*)elem2;
1613 return e1->line < e2->line ? -1 : e1->line > e2->line ? 1 : 0;
1614}
1615int comp_fileline (const void * elem1, const void * elem2)
1616{
1617 int iret;
1618 iret = comp_file(elem1,elem2);
1619 if(iret == 0)
1620 iret = comp_line(elem1,elem2);
1621 return iret;
1622}
1623void scanForVectorTypes(){
1624 for (mcount=0; mcount<MAXMALLOCSTOKEEP;mcount++) {
1625 if (mcheck[mcount]!=NULL) {
1626 if(mlineno[mcount]==5873){ //strstr("GeneratedCode.c",mplace[mcount]) &&
1627 //pexky _parentVector
1628 struct Vector * v = (struct Vector*)mcheck[mcount];
1629 printf("!%d!",v->n);
1630 }
1631 }
1632 }
1633}
1634void scanForFieldTypes(){
1635 for (mcount=0; mcount<MAXMALLOCSTOKEEP;mcount++) {
1636 if (mcheck[mcount]!=NULL) {
1637 if(mlineno[mcount]==105){ //strstr("GeneratedCode.c",mplace[mcount]) &&
1638 //pexky _parentVector
1639 union anyVrml u;
1640 struct Uni_String *us;
1641 //u.mfstring.p = mcheck[mcount];
1642 us = (struct Uni_String*)mcheck[mcount];
1643 printf("#%s#",us->strptr);
1644 //printf("!%p!",u.mfnode.p);
1645 }
1646 }
1647 }
1648}
1649void scanForCstringTypes(){
1650 for (mcount=0; mcount<MAXMALLOCSTOKEEP;mcount++) {
1651 if (mcheck[mcount]!=NULL) {
1652 if(mlineno[mcount]==456 || mlineno[mcount]==117){
1653 char *s = (char*)mcheck[mcount];
1654 printf(">%s<",s);
1655 }
1656 }
1657 }
1658}
1659void scanMallocTableOnQuit()
1660{
1661 //this version will sum up the lines were the mallocs are occuring that aren't freed
1662 int nlocs,j,iloc;
1663 size_t total;
1664 //scanForVectorTypes();
1665 scanForFieldTypes();
1666 //scanForCstringTypes();
1667 malloc_location *mlocs = malloc(sizeof(malloc_location)*MAXMALLOCSTOKEEP);
1668 memset(mlocs,0,sizeof(malloc_location)*MAXMALLOCSTOKEEP);
1669 nlocs = 0;
1670 for (mcount=0; mcount<MAXMALLOCSTOKEEP;mcount++) {
1671 if (mcheck[mcount]!=NULL) {
1672 //printf ("unfreed memory %x created at %s:%d \n",mcheck[mcount], mplace[mcount],mlineno[mcount]);
1673 iloc = -1;
1674 for(j=0;j<nlocs;j++){
1675 char *file, *mfile;
1676 int line, mline;
1677 file = mplace[mcount];
1678 line = mlineno[mcount];
1679 mfile = mlocs[j].fname;
1680 mline = mlocs[j].line;
1681 if(!file){
1682 printf("line %d",line);
1683 if(mfile) printf("mfile=%s",mfile);
1684 }
1685 if(!mfile){
1686 printf("line %d",line);
1687 if(file) printf("file=%s",file);
1688 }
1689 if(mline && mfile)
1690 if(!strcmp(file,mfile) && (line == mline) ){
1691 mlocs[j].count ++;
1692 mlocs[j].size += msize[mcount];
1693 iloc = j;
1694 break;
1695 }
1696 }
1697 if(iloc == -1){
1698 mlocs[nlocs].count = 1;
1699 mlocs[nlocs].fname = mplace[mcount];
1700 if(!mplace[mcount])
1701 printf("adding null place\n");
1702 mlocs[nlocs].line = mlineno[mcount];
1703 mlocs[nlocs].size = msize[mcount];
1704 nlocs++;
1705 }
1706 }
1707 }
1708 //sort by file, count or size
1709 if(1) qsort(mlocs,nlocs,sizeof(malloc_location),comp_fileline);
1710 if(0) qsort(mlocs,nlocs,sizeof(malloc_location),comp_line);
1711 if(0) qsort(mlocs,nlocs,sizeof(malloc_location),comp_file);
1712 if(0) qsort(mlocs,nlocs,sizeof(malloc_location),comp_count);
1713 if(0) qsort(mlocs,nlocs,sizeof(malloc_location),comp_size);
1714 printf("unfreed:\n");
1715 printf("%5s %8s %4s %55s\n","count","size","line","file");
1716 total = 0;
1717 for(j=0;j<nlocs;j++){
1718 printf("%5d %8d %4d %55s\n",mlocs[j].count,mlocs[j].size, mlocs[j].line,mlocs[j].fname);
1719 total += mlocs[j].size;
1720 }
1721 printf("total bytes not freed %d\n",total);
1722 free(mlocs);
1723 getchar();
1724}
1725
1726
1730void *freewrlMalloc(int line, char *file, size_t sz, int zeroData)
1731{
1732 void *rv;
1733 char myline[400];
1734
1735 mcheck_init();
1736
1737 rv = malloc(sz);
1738 if (rv==NULL) {
1739 sprintf (myline, "MALLOC PROBLEM - out of memory at %s:%d for %d",file,line,sz);
1740 outOfMemory (myline);
1741 }
1742 if(_noisy)printf ("%p malloc %d at %s:%d\n",rv,sz,file,line);
1743 if(!file)
1744 printf("");
1745 RESERVETABLE(rv,file,line,sz);
1746
1747 if (zeroData) bzero (rv, sz);
1748 return rv;
1749}
1750
1751void *freewrlRealloc (int line, char *file, void *ptr, size_t size)
1752{
1753 void *rv;
1754 char myline[400];
1755
1756 mcheck_init();
1757
1758 if(_noisy) printf ("%p xfree (from realloc) at %s:%d\n",ptr,file,line);
1759 rv = realloc (ptr,size);
1760 if (rv==NULL) {
1761 if (size != 0) {
1762 sprintf (myline, "REALLOC PROBLEM - out of memory at %s:%d size %d",file,line,size);
1763 outOfMemory (myline);
1764 }
1765 }
1766
1767 /* printf ("%x malloc (from realloc) %d at %s:%d\n",rv,size,file,line); */
1768 if(!file)
1769 printf("");
1770 FREETABLE(ptr,file,line);
1771 RESERVETABLE(rv,file,line,size);
1772
1773 return rv;
1774}
1775
1776
1777void *freewrlStrdup (int line, char *file, char *str)
1778{
1779 void *rv;
1780 char myline[400];
1781 mcheck_init();
1782 if(_noisy) printf("freewrlStrdup, at line %d file %s\n",line,file);
1783 rv = strdup (str);
1784 if (rv==NULL) {
1785 sprintf (myline, "STRDUP PROBLEM - out of memory at %s:%d ",file,line);
1786 outOfMemory (myline);
1787 }
1788 if(_noisy) printf ("freewrlStrdup, before reservetable\n");
1789 if(!file)
1790 printf("");
1791 RESERVETABLE(rv,file,line,strlen(str)+1);
1792 return rv;
1793}
1794void *mallocn_debug(int line, char *file, void *node,size_t size){
1795 void *p;
1796 struct X3D_Node *_node = X3D_NODE(node);
1797 p = freewrlMalloc(line,file,size,FALSE);
1798 register_node_gc(node,p);
1799 return p;
1800}
1801void *reallocn_debug(int line, char *file, void *node, void *pold, size_t newsize){
1802 void *p;
1803 struct X3D_Node *_node = X3D_NODE(node);
1804 unregister_node_gc(node,pold);
1805 p = freewrlRealloc(line,file,pold,newsize);
1806 register_node_gc(node,p);
1807 return p;
1808}
1809#else
1810void *mallocn(void *node,size_t size){
1811 void *p;
1812 // OLDCODE struct X3D_Node *_node = X3D_NODE(node);
1813 p = malloc(size);
1814 register_node_gc(node,p);
1815 return p;
1816}
1817void *reallocn(void *node, void *pold, size_t newsize){
1818 void *p;
1819 // OLDCODE struct X3D_Node *_node = X3D_NODE(node);
1820 unregister_node_gc(node,pold);
1821 p = realloc(pold,newsize);
1822 register_node_gc(node,p);
1823 return p;
1824}
1825#endif /* defined(DEBUG_MALLOC) */
1826
1827#if defined(_MSC_VER) && defined(W_DEBUG)
1828#include <crtdbg.h>
1829int check_memory(){
1830 static int check_memory_initialized = 0;
1831 int iret;
1832 if(!check_memory_initialized){
1833 // Get current flag
1834 int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
1835
1836 // Turn on leak-checking bit if not already
1837 tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
1838
1839 // Turn on CRT block checking bit if not already
1840 tmpFlag |= ~_CRTDBG_CHECK_CRT_DF;
1841
1842 // Set flag to the new value.
1843 _CrtSetDbgFlag( tmpFlag );
1844 check_memory_initialized = 1;
1845 }
1846 iret = _CrtCheckMemory();
1847 if(!iret){
1848 printf("ouch - memory violation\n");
1849 }
1850 return iret;
1851}
1852#else
1853int check_memory(){ return TRUE; }
1854#endif
1855
1856#endif