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