1 /***************************************************************************
2                           objects.cpp  -  global structures
3                              -------------------
4     begin                : July 22 2002
5     copyright            : (C) 2002 by Marc Schellens
6     email                : m_schellens@users.sf.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "includefirst.hpp"
19 
20 #include <limits>
21 #include <ios>
22 
23 #include "str.hpp"
24 #include "gdlexception.hpp"
25 #include "initsysvar.hpp"
26 #include "dnodefactory.hpp"
27 
28 #include "objects.hpp"
29 #include "graphicsdevice.hpp"
30 #include "overload.hpp"
31 
32 //#include "dinterpreter.hpp"
33 
34 #ifdef _OPENMP
35 #include <omp.h>
36 #endif
37 
38 #ifdef HAVE_LIBWXWIDGETS
39 #include "gdlwidget.hpp"
40 #endif
41 
42 #ifdef USE_PYTHON
43 #include "gdlpython.hpp"
44 #endif
45 
46 using namespace std;
47 
48 // DInterpreter* interpreter = NULL;
49 
50 // instantiate the global lists
51 VarListT      sysVarList;
52 VarListT      obsoleteSysVarList; //spceial case of very very old sysvar, some point to [parts of] values in sysVar (e.g. !CXMAX): cannot be destroyed in a .RESET (double free())
53 VarListT      sysVarRdOnlyList;
54 VarListT      sysVarNoSaveList;
55 
56 FunListT      funList;
57 ProListT      proList;
58 
59 LibFunListT   libFunList;
60 LibProListT   libProList;
61 
62 CommonListT   commonList;
63 
64 StructListT   structList;
65 
66 GDLFileListT  fileUnits;
67 
68 // flag for control-c
69 volatile bool sigControlC;
70 int           debugMode;
71 bool  strictInterpreter;
72 //	global garbage collection flag in support of HEAP_REFCOUNT:
73 static bool enabled_GC=true;
IsEnabledGC()74 	bool IsEnabledGC()  // Referenced from GDLInterpreter.hpp
75 	 { return enabled_GC; }
EnableGC(bool set=true)76 	void EnableGC( bool set=true) // same names, many contexts.
77 	 { enabled_GC = set; }
78 
79 namespace structDesc {
80   // set in InitStructs()
81   DStructDesc* LIST = NULL;
82   DStructDesc* HASH = NULL;
83   DStructDesc* GDL_CONTAINER = NULL;
84   DStructDesc* GDL_CONTAINER_NODE = NULL;
85   DStructDesc* GDL_HASHTABLEENTRY = NULL;
86   DStructDesc* IDLFFSHAPE = NULL;
87   DStructDesc* IDLFFXMLSAX = NULL;
88 }
89 
90 // for OpenMP
91 DLong CpuTPOOL_NTHREADS;
92 DLong64 CpuTPOOL_MIN_ELTS;
93 DLong64 CpuTPOOL_MAX_ELTS;
94 //const DULong64 CpuTPOOL_MAX_ELTS_max = numeric_limits<DLong64>::max();
95 
96 // instantiate own AST factory
97 //_DNodeFactory DNodeFactory;
98 antlr::ASTFactory DNodeFactory("DNode",DNode::factory);
99 
100 //do we use WxWidgets at all?
101 volatile bool useWxWidgets;
102 //do we use WxWidgets for graphics?
103 volatile bool useWxWidgetsForGraphics;
104 //do we use SVG for graphics in python notebook use?
105 volatile bool iAmANotebook;
106 //do we use name Devices differently among platforms?
107 volatile bool usePlatformDeviceName;
108 // do we force fonts to be the ugly IDL fonts?
109 volatile bool forceWxWidgetsUglyFonts;
110 
111 //do we favor SIMD-accelerated random number generation?
112 volatile bool useDSFMTAcceleration;
113 
ResetObjects()114 void ResetObjects()
115 {
116 #ifdef HAVE_LIBWXWIDGETS
117 
118   // un-initialize widget system
119   GDLWidget::UnInit();
120 #endif
121 
122   GraphicsDevice::DestroyDevices();
123 
124   fileUnits.clear();
125   cerr << flush; cout << flush; clog << flush;
126 
127   PurgeContainer(sysVarList);
128 //   sysVarRdOnlyList.clear(); // data is owned by sysVarList
129   PurgeContainer(funList);
130   PurgeContainer(proList);
131 
132   // delete common block data (which might be of type STRUCT)
133   CommonListT::iterator i;
134   for(i = commonList.begin(); i != commonList.end(); ++i)
135     { (*i)->DeleteData();}
136 
137   PurgeContainer(structList); // now deletes member subroutines (and they in turn common block references)
138   // hence delete common blocks after structList
139 
140   // should be ok now as data is already deleted //avoid purging commonlist-->crash (probably some COMMON structures already destroyed)
141   PurgeContainer(commonList);
142 
143   // don't purge library here
144 //   PurgeContainer(libFunList);
145 //   PurgeContainer(libProList);
146 
147 #ifdef USE_PYTHON
148   PythonEnd();
149 #endif
150 }
151 
152 // initialize struct descriptors which are not system variables
InitStructs()153 void InitStructs()
154 {
155   SpDInt    aInt;
156   SpDLong   aLong;
157   SpDString aString;
158   SpDByte   aByte;
159   SpDULong  aULong;
160   SpDLong64 aLong64;
161   SpDFloat  aFloat;
162   SpDDouble aDouble;
163   SpDComplex aComplex;
164   SpDComplexDbl aComplexDbl;
165 //  SpDStruct  aStruct;  //protected, we cannot use?
166   SpDInt   aColor( dimension(3));
167   SpDLong   aLongArr8( dimension(8));
168   SpDLong64   aLong64Arr8( dimension(8));
169   SpDDouble   aDoubleArr8( dimension(8));
170   SpDPtr    aPtrRef;
171   SpDObj    aObjRef;
172   SpDUInt   auInt;
173   SpDULong  auLong;
174   SpDULong64 auLong64;
175 
176   // OBJECTS =================================================
177 
178 //A structure where objects are in the order of GDL Typecodes. Useful.
179 
180   DStructDesc* gdltypecodes = new DStructDesc("GDL_TYPECODES_AS_STRUCT");
181    gdltypecodes->AddTag("GDL_UNDEF",   &aInt            );  //Danger! // 0 Undefined value, the default for new symbols
182    gdltypecodes->AddTag("GDL_BYTE",    &aByte           );  // 1 byte
183    gdltypecodes->AddTag("GDL_INT",	   &aInt            );  // 2 Integer scalar
184    gdltypecodes->AddTag("GDL_LONG",	   &aLong           );  // 3 long Integer scalar
185    gdltypecodes->AddTag("GDL_FLOAT",   &aFloat          );  // 4 Real scalar
186    gdltypecodes->AddTag("GDL_DOUBLE",  &aDouble         );  // 5 Double scalar
187    gdltypecodes->AddTag("GDL_COMPLEX", &aComplex        );  // 6 Complex scalar
188    gdltypecodes->AddTag("GDL_STRING",  &aString         );  // 7 String
189    gdltypecodes->AddTag("GDL_STRUCT",  &aInt            );  //Danger // 8 Struct
190    gdltypecodes->AddTag("GDL_COMPLEXDBL",  &aComplexDbl );  // 9 Complex double
191    gdltypecodes->AddTag("GDL_PTR",	   &aPtrRef         );  // 10 Pointer
192    gdltypecodes->AddTag("GDL_OBJ",     &aObjRef         );  // 11 Object reference
193    gdltypecodes->AddTag("GDL_UINT",    &auInt           );  // 12 unsigned int
194    gdltypecodes->AddTag("GDL_ULONG",   &auLong          );  // 13 unsigned long int
195    gdltypecodes->AddTag("GDL_LONG64",  &aLong64         );  // 14 64 bit integer
196    gdltypecodes->AddTag("GDL_ULONG64", &auLong64        );  // 15 unsigned 64 bit integer
197   // insert into structList
198   structList.push_back(gdltypecodes);
199 
200 
201   DStructDesc* gdl_object = new DStructDesc( GDL_OBJECT_NAME);
202   gdl_object->AddTag("IDL_OBJECT_TOP", &aLong64);
203   gdl_object->AddTag("__OBJ__", &aObjRef);
204   gdl_object->AddTag("IDL_OBJECT_BOTTOM", &aLong64);
205   // special for GDL_OBJECT ony
206   gdl_object->InitOperatorList();
207   // insert into structList
208   structList.push_back(gdl_object);
209 
210   DStructDesc* gdlList = new DStructDesc( "LIST");
211   gdlList->AddTag("GDL_CONTAINER_TOP", &aLong64);
212   gdlList->AddTag("GDLCONTAINERVERSION", &aInt);
213   gdlList->AddTag("PHEAD", &aPtrRef);
214   gdlList->AddTag("PTAIL", &aPtrRef);
215   gdlList->AddTag("NLIST", &aLong);
216   gdlList->AddTag("GDL_CONTAINER_BOTTOM", &aLong64);
217   // use operator overloading (note: gdl_object's operators are not set yet)
218   gdlList->AddParent(gdl_object);
219   // insert into structList
220   structList.push_back(gdlList);
221   structDesc::LIST = gdlList;
222 
223   DStructDesc* gdlContainerNode = new DStructDesc( "GDL_CONTAINER_NODE");
224   gdlContainerNode->AddTag("PNEXT", &aPtrRef);
225   gdlContainerNode->AddTag("PDATA", &aPtrRef);
226 //   gdlContainerNode->AddTag("OOBJ", &aObjRef);
227 //   gdlContainerNode->AddTag("FLAGS", &aLong);
228   // insert into structList
229   structList.push_back(gdlContainerNode);
230   structDesc::GDL_CONTAINER_NODE = gdlContainerNode;
231 
232   DStructDesc* gdlContainer = new DStructDesc( GDL_CONTAINER_NAME);
233   gdlContainer->AddTag("IDL_CONTAINER_TOP", &aLong64);
234   gdlContainer->AddTag("IDLCONTAINERVERSION", &aInt);
235   gdlContainer->AddTag("PHEAD", &aPtrRef);
236   gdlContainer->AddTag("PTAIL", &aPtrRef);
237   gdlContainer->AddTag("NLIST", &aLong);
238   gdlContainer->AddTag("IDL_CONTAINER_BOTTOM", &aLong64);
239 //  gdlContainer->AddParent(gdl_object);// no operator overloading
240   structList.push_back(gdlContainer);
241   structDesc::GDL_CONTAINER = gdlContainer;
242   DStructDesc* gdlHash = new DStructDesc( "HASH");
243   gdlHash->AddTag("TABLE_BITS", &aULong);
244   gdlHash->AddTag("TABLE_SIZE", &aULong);
245   gdlHash->AddTag("TABLE_COUNT", &aULong);
246   gdlHash->AddTag("TABLE_REMOVE", &aULong);
247   gdlHash->AddTag("TABLE_FOREACH", &aULong);
248   gdlHash->AddTag("TABLE_DATA", &aPtrRef);
249   // use operator overloading (note: gdl_object's operators are not set yet)
250   gdlHash->AddParent(gdl_object);
251   // insert into structList
252   structList.push_back(gdlHash);
253   structDesc::HASH = gdlHash;
254 
255   DStructDesc* gdlHashTE = new DStructDesc( "GDL_HASHTABLEENTRY");
256   gdlHashTE->AddTag("PKEY", &aPtrRef);
257   gdlHashTE->AddTag("PVALUE", &aPtrRef);
258   // insert into structList
259   structList.push_back(gdlHashTE);
260   structDesc::GDL_HASHTABLEENTRY = gdlHashTE;
261 
262 #ifdef USE_SHAPELIB
263   //for IDLffShape
264   DStructDesc* gdlffShape = new DStructDesc( "IDLFFSHAPE");
265   gdlffShape->AddTag("IDLFFSHAPE_TOP", &aLong64);
266   gdlffShape->AddTag("IDLFFSHAPEVERSION", &aInt);
267   gdlffShape->AddTag("FILENAME", &aString);
268   gdlffShape->AddTag("ISOPEN", &aInt);
269   gdlffShape->AddTag("SHPTYPE", &aInt);
270   gdlffShape->AddTag("PATTRIBUTE", &aPtrRef);
271   gdlffShape->AddTag("SHAPEHANDLE", &aLong64);
272   gdlffShape->AddTag("DBFHANDLE", &aLong64);
273   gdlffShape->AddTag("IDLFFSHAPE_BOTTOM", &aLong64);
274   // insert into structList
275   structList.push_back(gdlffShape);
276   structDesc::IDLFFSHAPE = gdlffShape;
277 
278 
279   DStructDesc* gdlffShape_entity = new DStructDesc( "IDL_SHAPE_ENTITY");
280   gdlffShape_entity->AddTag("SHAPE_TYPE", &aLong);
281   gdlffShape_entity->AddTag("ISHAPE", &aLong);
282   gdlffShape_entity->AddTag("BOUNDS", &aDoubleArr8);
283   gdlffShape_entity->AddTag("N_VERTICES", &aLong);
284   gdlffShape_entity->AddTag("VERTICES", &aPtrRef);
285   gdlffShape_entity->AddTag("MEASURE", &aPtrRef);
286   gdlffShape_entity->AddTag("N_PARTS", &aLong);
287   gdlffShape_entity->AddTag("PARTS", &aPtrRef);
288   gdlffShape_entity->AddTag("PART_TYPES", &aPtrRef);
289   gdlffShape_entity->AddTag("ATTRIBUTES", &aPtrRef);
290   // insert into structList
291   structList.push_back(gdlffShape_entity);
292 
293   DStructDesc* gdlffShape_attribute = new DStructDesc( "IDL_SHAPE_ATTRIBUTE");
294   gdlffShape_attribute->AddTag("NAME", &aString);
295   gdlffShape_attribute->AddTag("TYPE", &aLong);
296   gdlffShape_attribute->AddTag("WIDTH", &aLong);
297   gdlffShape_attribute->AddTag("PRECISION", &aLong);
298   // insert into structList
299   structList.push_back(gdlffShape_attribute);
300 #endif
301 
302 #ifdef USE_EXPAT
303 
304   //for IDLffXMLSAX
305   DStructDesc* gdlffXmlSax = new DStructDesc( "IDLFFXMLSAX");
306   gdlffXmlSax->AddTag("IDLFFXMLSAX_TOP", &aLong64);
307   gdlffXmlSax->AddTag("IDLFFXMLSAXVERSION", &aInt);
308   gdlffXmlSax->AddTag("VALIDATION_MODE", &aInt);
309   gdlffXmlSax->AddTag("HALT_PROCESSING", &aInt);
310   gdlffXmlSax->AddTag("_XML_PARSER", &aLong64);
311   gdlffXmlSax->AddTag("_XML_LOCATOR", &aLong64);
312   gdlffXmlSax->AddTag("IDLFFXMLSAX_BOTTOM", &aLong64);
313 //  gdlffXmlSax->AddParent(gdl_object);
314   // insert into structList
315   structList.push_back(gdlffXmlSax);
316   structDesc::IDLFFXMLSAX = gdlffXmlSax;
317 #endif
318 
319 
320 
321   // OBJECTS END =======================================================
322 
323   for (int big = 1; big >= 0; --big)
324   {
325     DStructDesc* gdl_size = new DStructDesc( big ? "IDL_SIZE64" : "IDL_SIZE");
326     gdl_size->AddTag("TYPE_NAME", &aString);
327     gdl_size->AddTag("STRUCTURE_NAME", &aString);
328     gdl_size->AddTag("TYPE", &aInt);
329     gdl_size->AddTag("FILE_LUN", &aInt);
330     if (big) {
331       gdl_size->AddTag("FILE_OFFSET",  &aLong64);
332       gdl_size->AddTag("N_ELEMENTS",  &aLong64);
333     } else {
334       gdl_size->AddTag("FILE_OFFSET",  &aLong);
335       gdl_size->AddTag("N_ELEMENTS",  &aLong);
336     }
337     gdl_size->AddTag("N_DIMENSIONS",  &aLong);
338     if (big) {
339       gdl_size->AddTag("DIMENSIONS",  &aLong64Arr8);
340     } else {
341       gdl_size->AddTag("DIMENSIONS",  &aLongArr8);
342     }
343     // insert into structList
344     structList.push_back(gdl_size);
345   }
346 
347   for (int big = 1; big >= 0; --big)
348   {
349     DStructDesc* fstat = new DStructDesc( big ? "FSTAT64" : "FSTAT");
350     fstat->AddTag("UNIT", &aLong);
351     fstat->AddTag("NAME", &aString);
352     fstat->AddTag("OPEN", &aByte);
353     fstat->AddTag("ISATTY", &aByte);
354     fstat->AddTag("ISAGUI", &aByte);
355     fstat->AddTag("INTERACTIVE", &aByte);
356     fstat->AddTag("XDR", &aByte);
357     fstat->AddTag("COMPRESS", &aByte);
358     fstat->AddTag("READ", &aByte);
359     fstat->AddTag("WRITE", &aByte);
360     fstat->AddTag("ATIME", &aLong64);
361     fstat->AddTag("CTIME", &aLong64);
362     fstat->AddTag("MTIME", &aLong64);
363     if (big)
364     {
365       fstat->AddTag("TRANSFER_COUNT", &aLong64);
366       fstat->AddTag("CUR_PTR", &aLong64);
367       fstat->AddTag("SIZE", &aLong64);
368       fstat->AddTag("REC_LEN", &aLong64);
369     }
370     else
371     {
372       fstat->AddTag("TRANSFER_COUNT", &aLong);
373       fstat->AddTag("CUR_PTR", &aLong);
374       fstat->AddTag("SIZE", &aLong);
375       fstat->AddTag("REC_LEN", &aLong);
376     }
377     // insert into structList
378     structList.push_back( fstat);
379   }
380 
381   DStructDesc* finfo = new DStructDesc("FILE_INFO");
382   finfo->AddTag("NAME", &aString);
383   finfo->AddTag("EXISTS", &aByte);
384   finfo->AddTag("READ", &aByte);
385   finfo->AddTag("WRITE", &aByte);
386   finfo->AddTag("EXECUTE", &aByte);
387   finfo->AddTag("REGULAR", &aByte);
388   finfo->AddTag("DIRECTORY", &aByte);
389   finfo->AddTag("BLOCK_SPECIAL", &aByte);
390   finfo->AddTag("CHARACTER_SPECIAL", &aByte);
391   finfo->AddTag("NAMED_PIPE", &aByte);
392   finfo->AddTag("SETUID", &aByte);
393   finfo->AddTag("SETGID", &aByte);
394   finfo->AddTag("SOCKET", &aByte);
395   finfo->AddTag("STICKY_BIT", &aByte);
396   finfo->AddTag("SYMLINK", &aByte);
397   finfo->AddTag("DANGLING_SYMLINK", &aByte);
398   finfo->AddTag("MODE", &aLong);
399   finfo->AddTag("ATIME", &aLong64);
400   finfo->AddTag("CTIME", &aLong64);
401   finfo->AddTag("MTIME", &aLong64);
402   finfo->AddTag("SIZE", &aLong64);
403   // insert into structList
404   structList.push_back( finfo);
405 
406   DStructDesc* memory = new DStructDesc("IDL_MEMORY");
407   memory->AddTag("CURRENT", &aLong);
408   memory->AddTag("NUM_ALLOC", &aLong);
409   memory->AddTag("NUM_FREE", &aLong);
410   memory->AddTag("HIGHWATER", &aLong);
411   // insert into structList
412   structList.push_back(memory);
413 
414   DStructDesc* memory64 = new DStructDesc("IDL_MEMORY64");
415   memory64->AddTag("CURRENT", &aLong64);
416   memory64->AddTag("NUM_ALLOC", &aLong64);
417   memory64->AddTag("NUM_FREE", &aLong64);
418   memory64->AddTag("HIGHWATER", &aLong64);
419   // insert into structList
420   structList.push_back(memory64);
421 
422   DStructDesc* machar = new DStructDesc( "MACHAR");
423   machar->AddTag("IBETA", &aLong);
424   machar->AddTag("IT", &aLong);
425   machar->AddTag("IRND", &aLong);
426   machar->AddTag("NGRD", &aLong);
427   machar->AddTag("MACHEP", &aLong);
428   machar->AddTag("NEGEP", &aLong);
429   machar->AddTag("IEXP", &aLong);
430   machar->AddTag("MINEXP", &aLong);
431   machar->AddTag("MAXEXP", &aLong);
432   machar->AddTag("EPS", &aFloat);
433   machar->AddTag("EPSNEG", &aFloat);
434   machar->AddTag("XMIN", &aFloat);
435   machar->AddTag("XMAX", &aFloat);
436   // insert into structList
437   structList.push_back( machar);
438 
439   DStructDesc* dmachar = new DStructDesc( "DMACHAR");
440   dmachar->AddTag("IBETA", &aLong);
441   dmachar->AddTag("IT", &aLong);
442   dmachar->AddTag("IRND", &aLong);
443   dmachar->AddTag("NGRD", &aLong);
444   dmachar->AddTag("MACHEP", &aLong);
445   dmachar->AddTag("NEGEP", &aLong);
446   dmachar->AddTag("IEXP", &aLong);
447   dmachar->AddTag("MINEXP", &aLong);
448   dmachar->AddTag("MAXEXP", &aLong);
449   dmachar->AddTag("EPS", &aDouble);
450   dmachar->AddTag("EPSNEG", &aDouble);
451   dmachar->AddTag("XMIN", &aDouble);
452   dmachar->AddTag("XMAX", &aDouble);
453   // insert into structList
454   structList.push_back( dmachar);
455 
456   // for internal usage. make event handler destroy the TLB widget
457   // attention: $WIDGET_DESTROY would identify this as an unnamed struct
458   // see DStructDesc constructor
459   DStructDesc* widgdestroy = new DStructDesc( "*WIDGET_DESTROY*");
460   widgdestroy->AddTag("ID", &aLong);
461   widgdestroy->AddTag("TOP", &aLong);
462   widgdestroy->AddTag("HANDLER", &aLong);
463   // insert into structList
464   structList.push_back( widgdestroy);
465 
466   // for internal usage. make event handler exit form event loop on TLB destruction without destroying (again) the TLB widget
467   DStructDesc* toplevelISdestroyed = new DStructDesc( "*TOPLEVEL_DESTROYED*");
468   toplevelISdestroyed->AddTag("ID", &aLong);
469   toplevelISdestroyed->AddTag("TOP", &aLong);
470   toplevelISdestroyed->AddTag("HANDLER", &aLong);
471   // insert into structList
472   structList.push_back( toplevelISdestroyed);
473 
474   //for internal usage: event structure used to pass any catched "C++" event (as in ThrowGDLException)
475   //back to $MAIN$ to process as a normal error like in e->Throw();
476   DStructDesc* WidRunTimeError = new DStructDesc( "*WIDGET_RUNTIME_ERROR*");
477   WidRunTimeError->AddTag("ID", &aLong);
478   WidRunTimeError->AddTag("TOP", &aLong);
479   WidRunTimeError->AddTag("HANDLER", &aLong);
480   WidRunTimeError->AddTag("MESSAGE", &aString);
481   // insert into structList
482   structList.push_back( WidRunTimeError);
483 
484   DStructDesc* widgbut = new DStructDesc( "WIDGET_BUTTON");
485   widgbut->AddTag("ID", &aLong);
486   widgbut->AddTag("TOP", &aLong);
487   widgbut->AddTag("HANDLER", &aLong);
488   widgbut->AddTag("SELECT", &aLong);
489   // insert into structList
490   structList.push_back( widgbut);
491 
492   DStructDesc* widgdlist = new DStructDesc( "WIDGET_DROPLIST");
493   widgdlist->AddTag("ID", &aLong);
494   widgdlist->AddTag("TOP", &aLong);
495   widgdlist->AddTag("HANDLER", &aLong);
496   widgdlist->AddTag("INDEX", &aLong);
497   // insert into structList
498   structList.push_back( widgdlist);
499 
500   DStructDesc* widgcbox = new DStructDesc( "WIDGET_COMBOBOX");
501   widgcbox->AddTag("ID", &aLong);
502   widgcbox->AddTag("TOP", &aLong);
503   widgcbox->AddTag("HANDLER", &aLong);
504   widgcbox->AddTag("INDEX", &aLong);
505   widgcbox->AddTag("STR", &aString);
506   // insert into structList
507   structList.push_back( widgcbox);
508 
509   DStructDesc* widglist = new DStructDesc( "WIDGET_LIST");
510   widglist->AddTag("ID", &aLong);
511   widglist->AddTag("TOP", &aLong);
512   widglist->AddTag("HANDLER", &aLong);
513   widglist->AddTag("INDEX", &aLong);
514   widglist->AddTag("CLICKS", &aLong);
515   // insert into structList
516   structList.push_back( widglist);
517 
518   DStructDesc* widgdtab = new DStructDesc( "WIDGET_TAB");
519   widgdtab->AddTag("ID", &aLong);
520   widgdtab->AddTag("TOP", &aLong);
521   widgdtab->AddTag("HANDLER", &aLong);
522   widgdtab->AddTag("TAB", &aLong);
523   // insert into structList
524   structList.push_back( widgdtab);
525 
526   DStructDesc* widgdsl = new DStructDesc( "WIDGET_SLIDER");
527   widgdsl->AddTag("ID", &aLong);
528   widgdsl->AddTag("TOP", &aLong);
529   widgdsl->AddTag("HANDLER", &aLong);
530   widgdsl->AddTag("VALUE", &aLong);
531   widgdsl->AddTag("DRAG", &aInt);
532   // insert into structList
533   structList.push_back( widgdsl);
534 
535   DStructDesc* widgbgroup =  new DStructDesc( "WIDGET_BGROUP");
536   widgbgroup->AddTag("ID", &aLong);
537   widgbgroup->AddTag("TOP", &aLong);
538   widgbgroup->AddTag("HANDLER", &aLong);
539   widgbgroup->AddTag("SELECT", &aLong);
540   widgbgroup->AddTag("VALUE", &aLong);
541   // insert into structList
542   structList.push_back(widgbgroup);
543 
544   DStructDesc* widgtxtc = new DStructDesc( "WIDGET_TEXT_CH");
545   widgtxtc->AddTag("ID", &aLong);
546   widgtxtc->AddTag("TOP", &aLong);
547   widgtxtc->AddTag("HANDLER", &aLong);
548   widgtxtc->AddTag("TYPE", &aInt); // 0
549   widgtxtc->AddTag("OFFSET", &aLong);
550   widgtxtc->AddTag("CH", &aByte);
551   // insert into structList
552   structList.push_back( widgtxtc);
553 
554   DStructDesc* widgtablec = new DStructDesc( "WIDGET_TABLE_CH");
555   widgtablec->AddTag("ID", &aLong);
556   widgtablec->AddTag("TOP", &aLong);
557   widgtablec->AddTag("HANDLER", &aLong);
558   widgtablec->AddTag("TYPE", &aInt); // 0
559   widgtablec->AddTag("OFFSET", &aLong);
560   widgtablec->AddTag("CH", &aByte);
561   widgtablec->AddTag("X", &aLong);
562   widgtablec->AddTag("Y", &aLong);
563   // insert into structList
564   structList.push_back( widgtablec);
565 
566   DStructDesc* widgtxtst = new DStructDesc( "WIDGET_TEXT_STR");
567   widgtxtst->AddTag("ID", &aLong);
568   widgtxtst->AddTag("TOP", &aLong);
569   widgtxtst->AddTag("HANDLER", &aLong);
570   widgtxtst->AddTag("TYPE", &aInt); // 1
571   widgtxtst->AddTag("OFFSET", &aLong);
572   widgtxtst->AddTag("STR", &aString);
573   // insert into structList
574   structList.push_back( widgtxtst);
575 
576   DStructDesc* widgtablest = new DStructDesc( "WIDGET_TABLE_STR");
577   widgtablest->AddTag("ID", &aLong);
578   widgtablest->AddTag("TOP", &aLong);
579   widgtablest->AddTag("HANDLER", &aLong);
580   widgtablest->AddTag("TYPE", &aInt); // 1
581   widgtablest->AddTag("OFFSET", &aLong);
582   widgtablest->AddTag("STR", &aString);
583   widgtablest->AddTag("X", &aLong);
584   widgtablest->AddTag("Y", &aLong);
585    // insert into structList
586   structList.push_back( widgtablest);
587 
588   DStructDesc* widgtxts = new DStructDesc( "WIDGET_TEXT_SEL");
589   widgtxts->AddTag("ID", &aLong);
590   widgtxts->AddTag("TOP", &aLong);
591   widgtxts->AddTag("HANDLER", &aLong);
592   widgtxts->AddTag("TYPE", &aInt); // 3
593   widgtxts->AddTag("OFFSET", &aLong);
594   widgtxts->AddTag("LENGTH", &aLong);
595   // insert into structList
596   structList.push_back( widgtxts);
597 
598   DStructDesc* widgtablesel = new DStructDesc( "WIDGET_TABLE_TEXT_SEL");
599   widgtablesel->AddTag("ID", &aLong);
600   widgtablesel->AddTag("TOP", &aLong);
601   widgtablesel->AddTag("HANDLER", &aLong);
602   widgtablesel->AddTag("TYPE", &aInt); // 3
603   widgtablesel->AddTag("OFFSET", &aLong);
604   widgtablesel->AddTag("LENGTH", &aLong);
605   widgtablesel->AddTag("X", &aLong);
606   widgtablesel->AddTag("Y", &aLong);
607   // insert into structList
608   structList.push_back( widgtablesel);
609 
610   DStructDesc* widgtablecelsel = new DStructDesc( "WIDGET_TABLE_CELL_SEL");
611   widgtablecelsel->AddTag("ID", &aLong);
612   widgtablecelsel->AddTag("TOP", &aLong);
613   widgtablecelsel->AddTag("HANDLER", &aLong);
614   widgtablecelsel->AddTag("TYPE", &aInt); // 4
615   widgtablecelsel->AddTag("SEL_LEFT", &aLong);
616   widgtablecelsel->AddTag("SEL_TOP", &aLong);
617   widgtablecelsel->AddTag("SEL_RIGHT", &aLong);
618   widgtablecelsel->AddTag("SEL_BOTTOM", &aLong);
619   // insert into structList
620   structList.push_back( widgtablecelsel);
621 
622   DStructDesc* widgtableceldesel = new DStructDesc( "WIDGET_TABLE_CELL_DESEL");
623   widgtableceldesel->AddTag("ID", &aLong);
624   widgtableceldesel->AddTag("TOP", &aLong);
625   widgtableceldesel->AddTag("HANDLER", &aLong);
626   widgtableceldesel->AddTag("TYPE", &aInt); // 9
627   widgtableceldesel->AddTag("SEL_LEFT", &aLong);
628   widgtableceldesel->AddTag("SEL_TOP", &aLong);
629   widgtableceldesel->AddTag("SEL_RIGHT", &aLong);
630   widgtableceldesel->AddTag("SEL_BOTTOM", &aLong);
631   // insert into structList
632   structList.push_back( widgtableceldesel);
633 
634   DStructDesc* widgtxtd = new DStructDesc( "WIDGET_TEXT_DEL");
635   widgtxtd->AddTag("ID", &aLong);
636   widgtxtd->AddTag("TOP", &aLong);
637   widgtxtd->AddTag("HANDLER", &aLong);
638   widgtxtd->AddTag("TYPE", &aInt); // 2
639   widgtxtd->AddTag("OFFSET", &aLong);
640   widgtxtd->AddTag("LENGTH", &aLong);
641   // insert into structList
642   structList.push_back( widgtxtd);
643 
644   DStructDesc* widgtabled = new DStructDesc( "WIDGET_TABLE_DEL");
645   widgtabled->AddTag("ID", &aLong);
646   widgtabled->AddTag("TOP", &aLong);
647   widgtabled->AddTag("HANDLER", &aLong);
648   widgtabled->AddTag("TYPE", &aInt); // 2
649   widgtabled->AddTag("OFFSET", &aLong);
650   widgtabled->AddTag("LENGTH", &aLong);
651   widgtabled->AddTag("X", &aLong);
652   widgtabled->AddTag("Y", &aLong);
653    // insert into structList
654   structList.push_back( widgtabled);
655 
656   DStructDesc* widgtablerowheight = new DStructDesc( "WIDGET_TABLE_ROW_HEIGHT");
657   widgtablerowheight->AddTag("ID", &aLong);
658   widgtablerowheight->AddTag("TOP", &aLong);
659   widgtablerowheight->AddTag("HANDLER", &aLong);
660   widgtablerowheight->AddTag("TYPE", &aInt); // 6
661   widgtablerowheight->AddTag("ROW", &aLong);
662   widgtablerowheight->AddTag("HEIGHT", &aLong);
663   // insert into structList
664   structList.push_back( widgtablerowheight);
665 
666   DStructDesc* widgtablecolwidth = new DStructDesc( "WIDGET_TABLE_COL_WIDTH");
667   widgtablecolwidth->AddTag("ID", &aLong);
668   widgtablecolwidth->AddTag("TOP", &aLong);
669   widgtablecolwidth->AddTag("HANDLER", &aLong);
670   widgtablecolwidth->AddTag("TYPE", &aInt); // 7
671   widgtablecolwidth->AddTag("COL", &aLong);
672   widgtablecolwidth->AddTag("WIDTH", &aLong);
673   // insert into structList
674   structList.push_back( widgtablecolwidth);
675 
676   DStructDesc* widgtableinvalidentry = new DStructDesc( "WIDGET_TABLE_INVALID_ENTRY");
677   widgtableinvalidentry->AddTag("ID", &aLong);
678   widgtableinvalidentry->AddTag("TOP", &aLong);
679   widgtableinvalidentry->AddTag("HANDLER", &aLong);
680   widgtableinvalidentry->AddTag("TYPE", &aInt); // 8
681   widgtableinvalidentry->AddTag("STR", &aString);
682   widgtableinvalidentry->AddTag("X", &aLong);
683   widgtableinvalidentry->AddTag("Y", &aLong);
684   // insert into structList
685   structList.push_back( widgtableinvalidentry);
686 
687   DStructDesc* widgnoevent = new DStructDesc( "WIDGET_NOEVENT");
688   widgnoevent->AddTag("ID", &aLong);
689   widgnoevent->AddTag("TOP", &aLong);
690   widgnoevent->AddTag("HANDLER", &aLong);
691   // insert into structList
692   structList.push_back( widgnoevent);
693 
694   DStructDesc* widgver = new DStructDesc( "WIDGET_VERSION");
695   widgver->AddTag("STYLE", &aString);
696   widgver->AddTag("TOOLKIT", &aString);
697   widgver->AddTag("RELEASE", &aString);
698   // insert into structList
699   structList.push_back( widgver);
700 
701   DStructDesc* widggeom = new DStructDesc( "WIDGET_GEOMETRY");
702   widggeom->AddTag("XOFFSET",&aFloat);
703   widggeom->AddTag("YOFFSET",&aFloat);
704   widggeom->AddTag("XSIZE",&aFloat);
705   widggeom->AddTag("YSIZE",&aFloat);
706   widggeom->AddTag("SCR_XSIZE",&aFloat);
707   widggeom->AddTag("SCR_YSIZE",&aFloat);
708   widggeom->AddTag("DRAW_XSIZE",&aFloat);
709   widggeom->AddTag("DRAW_YSIZE",&aFloat);
710   widggeom->AddTag("MARGIN",&aFloat);
711   widggeom->AddTag("XPAD",&aFloat);
712   widggeom->AddTag("YPAD",&aFloat);
713   widggeom->AddTag("SPACE",&aFloat);
714   // insert into structList
715   structList.push_back( widggeom);
716 
717   DStructDesc* widgdraw = new DStructDesc( "WIDGET_DRAW");
718   widgdraw->AddTag("ID", &aLong);
719   widgdraw->AddTag("TOP", &aLong);
720   widgdraw->AddTag("HANDLER", &aLong);
721   widgdraw->AddTag("TYPE", &aInt);
722   widgdraw->AddTag("X", &aLong);
723   widgdraw->AddTag("Y", &aLong);
724   widgdraw->AddTag("PRESS", &aByte);
725   widgdraw->AddTag("RELEASE", &aByte);
726   widgdraw->AddTag("CLICKS", &aLong);
727   widgdraw->AddTag("MODIFIERS", &aLong);
728   widgdraw->AddTag("CH", &aByte);
729   widgdraw->AddTag("KEY", &aLong);
730   // insert into structList
731   structList.push_back( widgdraw);
732 
733   DStructDesc* widgkbrdfocus = new DStructDesc( "WIDGET_KBRD_FOCUS");
734   widgkbrdfocus->AddTag("ID", &aLong);
735   widgkbrdfocus->AddTag("TOP", &aLong);
736   widgkbrdfocus->AddTag("HANDLER", &aLong);
737   widgkbrdfocus->AddTag("ENTER", &aInt);
738   structList.push_back( widgkbrdfocus);
739 
740   DStructDesc* widgcontext = new DStructDesc( "WIDGET_CONTEXT");
741   widgcontext->AddTag("ID", &aLong);
742   widgcontext->AddTag("TOP", &aLong);
743   widgcontext->AddTag("HANDLER", &aLong);
744   widgcontext->AddTag("X", &aLong);
745   widgcontext->AddTag("Y", &aLong);
746   widgcontext->AddTag("ROW", &aLong);
747   widgcontext->AddTag("COL", &aLong);
748   // insert into structList
749   structList.push_back( widgcontext);
750 
751   DStructDesc* widgtlb_size_events = new DStructDesc( "WIDGET_BASE");
752   widgtlb_size_events->AddTag("ID", &aLong);
753   widgtlb_size_events->AddTag("TOP", &aLong);
754   widgtlb_size_events->AddTag("HANDLER", &aLong);
755   widgtlb_size_events->AddTag("X", &aLong);
756   widgtlb_size_events->AddTag("Y", &aLong);
757   // insert into structList
758   structList.push_back( widgtlb_size_events);
759 
760   DStructDesc* widgtlb_move_events = new DStructDesc( "WIDGET_TLB_MOVE");
761   widgtlb_move_events->AddTag("ID", &aLong);
762   widgtlb_move_events->AddTag("TOP", &aLong);
763   widgtlb_move_events->AddTag("HANDLER", &aLong);
764   widgtlb_move_events->AddTag("X", &aLong);
765   widgtlb_move_events->AddTag("Y", &aLong);
766   // insert into structList
767   structList.push_back( widgtlb_move_events);
768 
769   DStructDesc* widgtlb_iconify_events = new DStructDesc( "WIDGET_TLB_ICONIFY");
770   widgtlb_iconify_events->AddTag("ID", &aLong);
771   widgtlb_iconify_events->AddTag("TOP", &aLong);
772   widgtlb_iconify_events->AddTag("HANDLER", &aLong);
773   widgtlb_iconify_events->AddTag("ICONIFIED", &aInt);
774   // insert into structList
775   structList.push_back( widgtlb_iconify_events);
776 
777   DStructDesc* widgtlb_kill_request_events = new DStructDesc( "WIDGET_KILL_REQUEST");
778   widgtlb_kill_request_events->AddTag("ID", &aLong);
779   widgtlb_kill_request_events->AddTag("TOP", &aLong);
780   widgtlb_kill_request_events->AddTag("HANDLER", &aLong);
781   // insert into structList
782   structList.push_back( widgtlb_kill_request_events);
783 
784   DStructDesc* widgtracking = new DStructDesc( "WIDGET_TRACKING");
785   widgtracking->AddTag("ID", &aLong);
786   widgtracking->AddTag("TOP", &aLong);
787   widgtracking->AddTag("HANDLER", &aLong);
788   widgtracking->AddTag("ENTER", &aInt);
789   // insert into structList
790   structList.push_back( widgtracking);
791 
792   DStructDesc* widgtimer = new DStructDesc( "WIDGET_TIMER");
793   widgtimer->AddTag("ID", &aLong);
794   widgtimer->AddTag("TOP", &aLong);
795   widgtimer->AddTag("HANDLER", &aLong);
796   // insert into structList
797   structList.push_back( widgtimer);
798 
799   DStructDesc* colo = new DStructDesc( "WIDGET_SYSTEM_COLORS");
800   colo->AddTag("DARK_SHADOW_3D", &aColor);
801   colo->AddTag("FACE_3D", &aColor);
802   colo->AddTag("LIGHT_EDGE_3D", &aColor);
803   colo->AddTag("LIGHT_3D", &aColor);
804   colo->AddTag("SHADOW_3D", &aColor);
805   colo->AddTag("ACTIVE_BORDER", &aColor);
806   colo->AddTag("ACTIVE_CAPTION", &aColor);
807   colo->AddTag("APP_WORKSPACE", &aColor);
808   colo->AddTag("DESKTOP", &aColor);
809   colo->AddTag("BUTTON_TEXT", &aColor);
810   colo->AddTag("CAPTION_TEXT", &aColor);
811   colo->AddTag("GRAY_TEXT", &aColor);
812   colo->AddTag("HIGHLIGHT", &aColor);
813   colo->AddTag("HIGHLIGHT_TEXT", &aColor);
814   colo->AddTag("INACTIVE_BORDER", &aColor);
815   colo->AddTag("INACTIVE_CAPTION", &aColor);
816   colo->AddTag("INACTIVE_CAPTION_TEXT", &aColor);
817   colo->AddTag("TOOLTIP_BK", &aColor);
818   colo->AddTag("TOOLTIP_TEXT", &aColor);
819   colo->AddTag("MENU", &aColor);
820   colo->AddTag("MENU_TEXT", &aColor);
821   colo->AddTag("SCROLLBAR", &aColor);
822   colo->AddTag("WINDOW_BK", &aColor);
823   colo->AddTag("WINDOW_FRAME", &aColor);
824   colo->AddTag("WINDOW_TEXT", &aColor);
825   // insert into structList
826   structList.push_back( colo);
827 
828  DStructDesc* dropstruct = new DStructDesc( "WIDGET_DROP");
829   dropstruct->AddTag("ID", &aLong);
830   dropstruct->AddTag("TOP", &aLong);
831   dropstruct->AddTag("HANDLER", &aLong);
832   dropstruct->AddTag("DRAG_ID", &aLong);
833   dropstruct->AddTag("POSITION", &aInt);
834   dropstruct->AddTag("X", &aLong);
835   dropstruct->AddTag("Y", &aLong);
836   dropstruct->AddTag("MODIFIERS", &aInt);
837   // insert into structList
838   structList.push_back( dropstruct);
839 
840  DStructDesc* treeselstruct = new DStructDesc( "WIDGET_TREE_SEL");
841   treeselstruct->AddTag("ID", &aLong);
842   treeselstruct->AddTag("TOP", &aLong);
843   treeselstruct->AddTag("HANDLER", &aLong);
844   treeselstruct->AddTag("TYPE", &aInt);
845   treeselstruct->AddTag("CLICKS", &aLong);
846   // insert into structList
847   structList.push_back( treeselstruct);
848 
849  DStructDesc* treeexpandstruct = new DStructDesc( "WIDGET_TREE_EXPAND");
850   treeexpandstruct->AddTag("ID", &aLong);
851   treeexpandstruct->AddTag("TOP", &aLong);
852   treeexpandstruct->AddTag("HANDLER", &aLong);
853   treeexpandstruct->AddTag("TYPE", &aInt);
854   treeexpandstruct->AddTag("EXPAND", &aLong);
855   // insert into structList
856   structList.push_back( treeexpandstruct);
857 
858   DStructDesc* treeecheckedstruct = new DStructDesc( "WIDGET_TREE_CHECKED");
859   treeecheckedstruct->AddTag("ID", &aLong);
860   treeecheckedstruct->AddTag("TOP", &aLong);
861   treeecheckedstruct->AddTag("HANDLER", &aLong);
862   treeecheckedstruct->AddTag("TYPE", &aInt);
863   treeecheckedstruct->AddTag("STATE", &aLong);
864   // insert into structList
865   structList.push_back( treeecheckedstruct);
866 
867  DStructDesc* idltracebackstruct = new DStructDesc( "IDL_TRACEBACK");
868   idltracebackstruct->AddTag("ROUTINE", &aString);
869   idltracebackstruct->AddTag("FILENAME", &aString);
870   idltracebackstruct->AddTag("LINE", &aLong);
871   idltracebackstruct->AddTag("LEVEL", &aLong);
872   idltracebackstruct->AddTag("IS_FUNCTION", &aByte);
873   idltracebackstruct->AddTag("METHOD", &aByte);
874   idltracebackstruct->AddTag("RESTORED", &aByte);
875   idltracebackstruct->AddTag("SYSTEM", &aByte);
876   // insert into structList
877   structList.push_back( idltracebackstruct);
878 
879 //template for future uses:
880 // DStructDesc* struct = new DStructDesc( "WIDGET_DROP");
881 //  struct->AddTag("ID", &aLong);
882 //  struct->AddTag("TOP", &aLong);
883 //  struct->AddTag("HANDLER", &aLong);
884 //  // insert into structList
885 //  structList.push_back( struct);
886 }
887 
InitObjects()888 void InitObjects()
889 {
890 
891   sigControlC = false;
892   debugMode   = 0;
893 
894   fileUnits.resize( maxLun); // 0-127 -> 1-128 within GDL for files
895 
896   // initialize GDL system variables
897   SysVar::InitSysVar();
898 
899   // initialize struct descriptors which are not system variables
900   InitStructs();
901   // add internal memeber subroutines
902   SetupOverloadSubroutines();
903 
904   // graphic devices must be initialized after system variables.
905   // !D must already exist
906   // We need to initialize the multi-device object that inherits from the single-device object.
907   GraphicsMultiDevice::Init();
908 
909   string gdlPath=GetEnvString("GDL_PATH");
910   if( gdlPath == "") gdlPath=GetEnvString("IDL_PATH");
911   if( gdlPath == "") gdlPath = "+" GDLDATADIR "/lib";
912   SysVar::SetGDLPath( gdlPath);
913 }
914 
915 // returns GDL lun, 0 on failure
GetLUN()916 DLong GetLUN()
917 {
918   for( DLong lun=maxUserLun+1; lun <= fileUnits.size(); lun++)
919     if( !fileUnits[ lun-1].InUse() && !fileUnits[ lun-1].GetGetLunLock())
920     {
921       fileUnits[ lun-1].SetGetLunLock( true);
922       return lun;
923     }
924 
925   return 0;
926 }
IsRelaxed()927 bool IsRelaxed(){return !strictInterpreter;}
SetStrict(bool value)928 void SetStrict(bool value){strictInterpreter=value;}
929 
930 // for semantic predicate
IsFun(antlr::RefToken rT1)931 bool IsFun(antlr::RefToken rT1)
932 {
933   antlr::Token& T1=*rT1;
934 
935   // search for T1.getText() in function table and path
936   string searchName=StrUpCase(T1.getText());
937 
938 //  cout << "IsFun: Searching for: " << searchName << endl;
939 
940 // Speeds up the process of finding (in gdlc.g) if a syntax like foo(bar) is a call to the function 'foo'
941 // or the 'bar' element of array 'foo'.
942   LibFunListT::iterator p=find_if(libFunList.begin(),libFunList.end(),
943 			       Is_eq<DLibFun>(searchName));
944   if( p != libFunList.end()) if( *p != NULL) return true;
945 
946   FunListT::iterator q=find_if(funList.begin(),funList.end(),
947 			       Is_eq<DFun>(searchName));
948   if( q != funList.end()) if( *q != NULL) return true;
949 
950   //  cout << "Not found: " << searchName << endl;
951 
952   return false;
953 }
954 
ProIx(const string & n)955 int ProIx(const string& n)
956 {
957 SizeT nF=proList.size();
958 for( SizeT i=0; i<nF; i++) if( Is_eq<DPro>(n)(proList[i]))
959   return (int)i;
960 return -1;
961 }
962 
FunIx(const string & n)963 int FunIx(const string& n)
964 {
965 SizeT nF=funList.size();
966 for( SizeT i=0; i<nF; i++) if( Is_eq<DFun>(n)(funList[i]))
967   return (int)i;
968 return -1;
969 }
970 
LibProIx(const string & n)971 int LibProIx(const string& n)
972 {
973   SizeT nF=libProList.size();
974   for( SizeT i=0; i<nF; i++)
975     {
976       if( Is_eq<DLibPro>(n)(libProList[i])) return (int)i;
977     }
978   return -1;
979 }
980 
LibFunIx(const string & n)981 int LibFunIx(const string& n)
982 {
983   SizeT nF=libFunList.size();
984 
985   for( SizeT i=0; i<nF; i++)
986     {
987       if( Is_eq<DLibFun>(n)(libFunList[i])) return (int)i;
988     }
989   return -1;
990 }
991 
992 // returns the endian of the current machine
BigEndian()993 bool BigEndian()
994 {
995   // a long should at least have two bytes
996   // big endian -> msb first (msb is 0 here)
997   static const unsigned long int s = 0x0001;
998   static const bool bigEndian = !(*reinterpret_cast<const unsigned char*>( &s));
999   return bigEndian;
1000 }
1001 
1002 // test---------------
1003 
breakpoint()1004 void breakpoint()
1005 {
1006   static SizeT num=1;
1007   cout << "objects.cpp: at breakpoint(): " << num << endl;
1008   num++;
1009 }
1010 
1011 
1012 #ifndef _OPENMP
get_suggested_omp_num_threads()1013 int get_suggested_omp_num_threads() {
1014   return 1;
1015 }
1016 #endif
1017 
1018 #if defined _OPENMP
get_suggested_omp_num_threads()1019 int get_suggested_omp_num_threads() {
1020 
1021   int default_num_threads=1, suggested_num_threads=1;
1022 
1023   char* env_var_c;
1024   env_var_c = getenv ("OMP_NUM_THREADS");
1025   if(env_var_c)
1026     {
1027       return atoi(env_var_c);
1028     }
1029   //    cout<<"OMP_NUM_THREADS is not defined"<<endl;
1030 
1031   //set number of threads for appropriate OS
1032   int avload = 0;
1033   int nbofproc = omp_get_num_procs();
1034   default_num_threads = nbofproc; //must be the default!!!
1035   FILE *iff;
1036 
1037 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
1038   //  cout<<"is MAC/*BSD"<<endl;
1039   iff= popen("echo $(sysctl -n vm.loadavg|cut -d\" \" -f 3)", "r");
1040   if (!iff)
1041     {
1042       return default_num_threads;
1043     }
1044 
1045 #elif defined(__linux__) || defined(__gnu_linux__) || defined(linux)
1046   //cout<<"is linux"<<endl;
1047   iff= popen("cat /proc/loadavg |cut -d\" \" -f3", "r");
1048   if (!iff)
1049     {
1050       return default_num_threads;
1051     }
1052 
1053 #elif defined (__unix) || defined(__unix__)
1054   iff=freopen("/proc/loadavg","r",stderr);
1055   fclose(stderr);
1056   if(!iff)
1057     {
1058       cout<<"your OS is not supported"<<endl;
1059       return default_num_threads;
1060     }
1061   iff= popen("cat /proc/loadavg 2>/dev/null|cut -d\" \" -f3", "r");
1062   if (!iff)
1063     {
1064       return default_num_threads;
1065     }
1066 
1067 
1068 #elif defined(_WIN32)
1069 #if 0
1070   //cout<<"get_suggested_omp_num_threads(): is windows"<<endl;
1071   iff= _popen("wmic cpu get loadpercentage|more +1", "r");
1072   if (!iff)
1073     {
1074       return default_num_threads;
1075     }
1076   char buffer[4];
1077   char* c;
1078   c=fgets(buffer, sizeof(buffer), iff);
1079   _pclose(iff);
1080   if(!c)
1081     {
1082       return default_num_threads;
1083     }
1084   int count=0;
1085   while(count < sizeof(buffer) && buffer[count]!='\0' && buffer[count]!=' ')count++;
1086   for(int i=1,j=1;i<=count;i++,j*=10)
1087   {
1088     if( buffer[count-i] != ' ' && buffer[count-i] != '\t')
1089       avload+=(buffer[count-i]-'0')*j;
1090   }
1091   suggested_num_threads=nbofproc-(int)(avload*((float)nbofproc/100)+0.5);
1092   return suggested_num_threads;
1093 #elif 1
1094    return nbofproc+2;
1095 #endif
1096 #else
1097   cout<<"Can't define your OS"<<endl;
1098   return default_num_threads;
1099 #endif
1100 
1101   //  cout << "Nb Procs.: " << nbofproc <<  endl;
1102   // cout << "nb Thead computed: " << nbofproc-(int)(avload+0.5) << endl;
1103 
1104   // if the following is commented out, there is no return statement
1105   // this lead to FILE_INFO in TEST_FILE_COPY fail
1106 #if !defined(_WIN32)
1107 
1108   char buffer[4];
1109   char* c;
1110   c=fgets(buffer, sizeof(buffer), iff);
1111   pclose(iff);
1112   if(!c)
1113     {
1114       return default_num_threads;
1115     }
1116   float la;
1117   if (sscanf(buffer, "%f", &la)!=1) return default_num_threads;
1118 //  cout<<la<<endl;
1119   suggested_num_threads=max(1,nbofproc-int(la));
1120 //  cout<<suggested_num_threads<<endl;
1121 #endif
1122   return suggested_num_threads;
1123 }
1124 #endif
1125 
1126 
1127