1 
2 /******************************************************************************
3 * MODULE     : basic.hpp
4 * DESCRIPTION: see basic.cpp
5 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11 
12 #ifndef BASIC_H
13 #define BASIC_H
14 #include "fast_alloc.hpp"
15 #include <math.h>
16 
17 #ifdef HAVE_INTPTR_T
18 #ifdef HAVE_INTTYPES_H
19 #include <inttypes.h>
20 #endif
21 #ifdef HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24 #else
25 typedef long intptr_t;
26 #endif
27 
28 #ifdef OS_WIN32
29 #define LESSGTR
30 #else
31 #define LESSGTR <>
32 #endif
33 
34 #define TM_DEBUG(x)
35 typedef int SI;
36 typedef unsigned int SN;
37 typedef short HI;
38 typedef unsigned short HN;
39 typedef char QI;
40 typedef unsigned char QN;
41 #ifdef OS_WIN32
42 typedef __int64 DI;
43 typedef unsigned __int64 DN;
44 #else
45 typedef long long int DI;
46 typedef unsigned long long int DN;
47 #endif
48 typedef void* pointer;
49 typedef unsigned int color;
50 #define MAX_SI 0x7fffffff
51 #define MIN_SI 0x80000000
52 
53 /******************************************************************************
54 * debugging
55 ******************************************************************************/
56 
57 #if (defined OS_WIN32 || defined __SUNPRO_CC || defined __clang__)
58 #define STACK_NEW_ARRAY(name,T,size) T* name= tm_new_array<T> (size)
59 #define STACK_DELETE_ARRAY(name) tm_delete_array (name)
60 #else
61 #define STACK_NEW_ARRAY(name,T,size) T name[size]
62 #define STACK_DELETE_ARRAY(name)
63 #endif
64 
65 enum { DEBUG_FLAG_AUTO, DEBUG_FLAG_VERBOSE, DEBUG_FLAG_EVENTS,
66        DEBUG_FLAG_STD, DEBUG_FLAG_IO, DEBUG_FLAG_BENCH,
67        DEBUG_FLAG_HISTORY, DEBUG_FLAG_QT, DEBUG_FLAG_QT_WIDGETS,
68        DEBUG_FLAG_KEYBOARD, DEBUG_FLAG_PACKRAT, DEBUG_FLAG_FLATTEN,
69        DEBUG_FLAG_CORRECT };
70 bool debug (int which, bool write_flag= false);
71 int  debug_off ();
72 void debug_on (int status);
73 class string;
74 void debug_set (string s, bool flag);
75 bool debug_get (string s);
76 #define DEBUG_AUTO (debug (DEBUG_FLAG_AUTO))
77 #define DEBUG_VERBOSE (debug (DEBUG_FLAG_VERBOSE))
78 #define DEBUG_EVENTS (debug (DEBUG_FLAG_EVENTS))
79 #define DEBUG_STD (debug (DEBUG_FLAG_STD))
80 #define DEBUG_IO (debug (DEBUG_FLAG_IO))
81 #define DEBUG_BENCH (debug (DEBUG_FLAG_BENCH))
82 #define DEBUG_HISTORY (debug (DEBUG_FLAG_HISTORY))
83 #define DEBUG_QT (debug (DEBUG_FLAG_QT))
84 #define DEBUG_QT_WIDGETS (debug (DEBUG_FLAG_QT_WIDGETS))
85 #define DEBUG_KEYBOARD (debug (DEBUG_FLAG_KEYBOARD))
86 #define DEBUG_PACKRAT (debug (DEBUG_FLAG_PACKRAT))
87 #define DEBUG_FLATTEN (debug (DEBUG_FLAG_FLATTEN))
88 #define DEBUG_CORRECT (debug (DEBUG_FLAG_CORRECT))
89 #define DEBUG_AQUA (debug (DEBUG_FLAG_QT))
90 #define DEBUG_AQUA_WIDGETS (debug (DEBUG_FLAG_QT_WIDGETS))
91 
92 #define USE_EXCEPTIONS
93 void tm_failure (const char* msg);
94 #ifdef USE_EXCEPTIONS
95 extern string the_exception;
96 void tm_throw (const char* msg);
97 void handle_exceptions ();
98 #define ASSERT(cond,msg) { if (!(cond)) tm_throw (msg); }
99 #define FAILED(msg) { tm_throw (msg); }
100 #else
101 #ifdef DEBUG_ASSERT
102 #include <assert.h>
103 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); assert (cond); } }
104 #define FAILED(msg) { tm_failure (msg); assert (false); }
105 #else
106 #define ASSERT(cond,msg) { if (!(cond)) { tm_failure (msg); } }
107 #define FAILED(msg) { tm_failure (msg); }
108 #endif
109 #endif
110 
111 class tree;
112 void debug_message (string channel, string msg);
113 void debug_formatted (string channel, tree msg);
114 tree get_debug_messages (string kind, int max_number);
115 void clear_debug_messages ();
116 void clear_debug_messages (string channel);
117 
118 /******************************************************************************
119 * miscellaneous routines
120 ******************************************************************************/
121 
min(SI i,SI j)122 inline SI min (SI i, SI j) { if (i<j) return i; else return j; }
max(SI i,SI j)123 inline SI max (SI i, SI j) { if (i>j) return i; else return j; }
min(DI i,DI j)124 inline DI min (DI i, DI j) { if (i<j) return i; else return j; }
max(DI i,DI j)125 inline DI max (DI i, DI j) { if (i>j) return i; else return j; }
min(double i,double j)126 inline double min (double i, double j) { if (i<j) return i; else return j; }
max(double i,double j)127 inline double max (double i, double j) { if (i>j) return i; else return j; }
hash(int i)128 inline int hash (int i) { return i; }
hash(long int i)129 inline int hash (long int i) { return (int) i; }
hash(DI i)130 inline int hash (DI i) { return (int) i; }
hash(unsigned int i)131 inline int hash (unsigned int i) { return i; }
hash(unsigned long int i)132 inline int hash (unsigned long int i) { return (int) i; }
hash(DN i)133 inline int hash (DN i) { return (int) i; }
hash(pointer ptr)134 inline int hash (pointer ptr) {
135   return ((int) ((intptr_t) ptr)) + (((int) ((intptr_t) ptr)) % 19); }
hash(float x)136 inline int hash (float x) {
137   union { int n; float d; } u;
138   u.d= x; return u.n & 0xffffffff; }
hash(double x)139 inline int hash (double x) {
140   union { DI n; double d; } u;
141   u.d= x; return (int) (u.n ^ (u.n >> 32)); }
copy(int x)142 inline int copy (int x) { return x; }
as_int(double x)143 inline SI as_int (double x) { return (SI) floor (x + 0.5); }
tm_round(double x)144 inline double tm_round (double x) { return floor (x + 0.5); }
145 
146 enum display_control { INDENT, UNINDENT, HRULE, LF };
147 tm_ostream& operator << (tm_ostream& out, display_control ctrl);
148 
149 bool gui_is_x ();
150 bool gui_is_qt ();
151 bool os_win32 ();
152 bool os_mingw ();
153 bool os_macos ();
154 bool use_macos_fonts ();
155 const char* default_look_and_feel ();
156 
157 template<typename T>
158 struct type_helper {
159   static int id;
160   static T init;
init_valtype_helper161   static inline T init_val () { return T (); }
162 };
163 
164 int new_type_identifier ();
165 template<typename T> int type_helper<T>::id  = new_type_identifier ();
166 template<typename T> T   type_helper<T>::init= T ();
167 
168 #ifdef QTTEXMACS
169 //#define QT_CPU_FIX 1
170 #ifdef QT_CPU_FIX
171 void tm_wake_up ();
172 void tm_sleep ();
173 #endif
174 #endif
175 
176 /******************************************************************************
177 * concrete and abstract base structures
178 ******************************************************************************/
179 
180 extern int concrete_count;
181 struct concrete_struct {
182   int ref_count;
concrete_structconcrete_struct183   inline concrete_struct (): ref_count (1) { TM_DEBUG(concrete_count++); }
~concrete_structconcrete_struct184   virtual inline ~concrete_struct () { TM_DEBUG(concrete_count--); }
185 };
186 
187 extern int abstract_count;
188 struct abstract_struct {
189   int ref_count;
abstract_structabstract_struct190   inline abstract_struct (): ref_count (0) { TM_DEBUG(abstract_count++); }
~abstract_structabstract_struct191   virtual inline ~abstract_struct () { TM_DEBUG(abstract_count--); }
192 };
193 
194 /******************************************************************************
195 * indirect structures
196 ******************************************************************************/
197 
198 #define INC_COUNT(R) { (R)->ref_count++; }
199 #define DEC_COUNT(R) { if(0==--((R)->ref_count)) { tm_delete (R);}}
200 //#define DEC_COUNT(R) { if(0==--((R)->ref_count)) { tm_delete (R); R=NULL;}}
201 #define INC_COUNT_NULL(R) { if ((R)!=NULL) (R)->ref_count++; }
202 /*#define DEC_COUNT_NULL(R) \
203   { if ((R)!=NULL && 0==--((R)->ref_count)) { tm_delete (R); } } */
204 #define DEC_COUNT_NULL(R) \
205   { if ((R)!=NULL && 0==--((R)->ref_count)) { tm_delete (R); R=NULL;} }
206 
207 // concrete
208 #define CONCRETE(PTR)               \
209   PTR##_rep *rep;                   \
210 public:                             \
211   inline PTR (const PTR&);          \
212   inline ~PTR ();                   \
213   inline PTR##_rep* operator -> (); \
214   inline PTR& operator = (PTR x)
215 #define CONCRETE_CODE(PTR)                       \
216   inline PTR::PTR (const PTR& x):                \
217     rep(x.rep) { INC_COUNT (this->rep); }        \
218   inline PTR::~PTR () { DEC_COUNT (this->rep); } \
219   inline PTR##_rep* PTR::operator -> () {        \
220     return rep; }                                \
221   inline PTR& PTR::operator = (PTR x) {          \
222     INC_COUNT (x.rep); DEC_COUNT (this->rep);    \
223     this->rep=x.rep; return *this; }
224 
225 // definition for 1 parameter template classes
226 #define CONCRETE_TEMPLATE(PTR,T)      \
227   PTR##_rep<T> *rep;                  \
228 public:                               \
229   inline PTR (const PTR<T>&);         \
230   inline ~PTR ();                     \
231   inline PTR##_rep<T>* operator -> (); \
232   inline PTR<T>& operator = (PTR<T> x)
233 #define CONCRETE_TEMPLATE_CODE(PTR,TT,T)                          \
234   template<TT T> inline PTR<T>::PTR (const PTR<T>& x):            \
235     rep(x.rep) { INC_COUNT (this->rep); }                         \
236   template<TT T> inline PTR<T>::~PTR() { DEC_COUNT (this->rep); } \
237   template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () {    \
238     return this->rep; }                                           \
239   template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) {   \
240     INC_COUNT (x.rep); DEC_COUNT (this->rep);                     \
241     this->rep=x.rep; return *this; }
242 
243 // definition for 2 parameter template classes
244 #define CONCRETE_TEMPLATE_2(PTR,T1,T2)     \
245   PTR##_rep<T1,T2> *rep;                   \
246 public:                                    \
247   inline PTR (const PTR<T1,T2>&);          \
248   inline ~PTR ();                          \
249   inline PTR##_rep<T1,T2>* operator -> (); \
250   inline PTR<T1,T2>& operator = (PTR<T1,T2> x)
251 #define CONCRETE_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                           \
252   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x):       \
253     rep(x.rep) { INC_COUNT (this->rep); }                                     \
254   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::~PTR () { DEC_COUNT(this->rep);} \
255   template<TT1 T1,TT2 T2> inline PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () \
256     { return this->rep; }                                                     \
257   template <TT1 T1,TT2 T2>                                                    \
258   inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) {                  \
259     INC_COUNT (x.rep); DEC_COUNT (this->rep);                                 \
260     this->rep=x.rep; return *this; }
261 // end concrete
262 
263 // abstract
264 #define ABSTRACT(PTR) \
265   CONCRETE(PTR);      \
266   inline PTR (PTR##_rep*)
267 #define ABSTRACT_CODE(PTR) \
268   CONCRETE_CODE(PTR) ;     \
269   inline PTR::PTR (PTR##_rep* rep2): rep(rep2) { INC_COUNT (this->rep); }
270 #define ABSTRACT_TEMPLATE(PTR,T) \
271   CONCRETE_TEMPLATE(PTR,T);      \
272   inline PTR (PTR##_rep<T>*)
273 #define ABSTRACT_TEMPLATE_CODE(PTR,TT,T)                  \
274   CONCRETE_TEMPLATE_CODE(PTR,TT,T);                       \
275   template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2): \
276     rep(rep2) { INC_COUNT (this->rep); }
277 // end abstract
278 
279 /******************************************************************************
280 * null indirect structures
281 ******************************************************************************/
282 
283 // concrete_null
284 #define CONCRETE_NULL(PTR) \
285   CONCRETE(PTR);           \
286   inline PTR();            \
287   friend bool is_nil /*LESSGTR*/ (PTR x)
288 #define CONCRETE_NULL_CODE(PTR)                         \
289   inline PTR::PTR (): rep(NULL) {}                      \
290   inline PTR::PTR (const PTR& x):                       \
291     rep(x.rep) { INC_COUNT_NULL (this->rep); }          \
292   inline PTR::~PTR() { DEC_COUNT_NULL (this->rep); }    \
293   inline PTR##_rep* PTR::operator -> () {               \
294     return this->rep; }                                 \
295   inline PTR& PTR::operator = (PTR x) {                 \
296     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep); \
297     this->rep=x.rep; return *this; }                    \
298   inline bool is_nil (PTR x) { return x.rep==NULL; }
299 #define CONCRETE_NULL_TEMPLATE(PTR,T) \
300   CONCRETE_TEMPLATE(PTR,T);           \
301   inline PTR();                       \
302   friend bool is_nil LESSGTR (PTR<T> x)
303 #define CONCRETE_NULL_TEMPLATE_CODE(PTR,TT,T)                           \
304   template<TT T> inline PTR<T>::PTR (): rep(NULL) {}                    \
305   template<TT T> inline PTR<T>::PTR (const PTR<T>& x):                  \
306     rep(x.rep) { INC_COUNT_NULL (this->rep); }                          \
307   template<TT T> inline PTR<T>::~PTR () { DEC_COUNT_NULL (this->rep); } \
308   template<TT T> inline PTR##_rep<T>* PTR<T>::operator -> () {          \
309     return this->rep; }                                                 \
310   template<TT T> inline PTR<T>& PTR<T>::operator = (PTR<T> x) {         \
311     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep);                 \
312     this->rep=x.rep; return *this; }                                    \
313   template<TT T> inline bool is_nil (PTR<T> x) { return x.rep==NULL; }
314 
315 #define CONCRETE_NULL_TEMPLATE_2(PTR,T1,T2) \
316   CONCRETE_TEMPLATE_2(PTR,T1,T2);           \
317   inline PTR();                             \
318   friend bool is_nil LESSGTR (PTR<T1,T2> x)
319 #define CONCRETE_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                  \
320   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (): rep(NULL) {}        \
321   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::PTR (const PTR<T1,T2>& x):  \
322     rep(x.rep) { INC_COUNT_NULL (this->rep); }                            \
323   template<TT1 T1, TT2 T2> inline PTR<T1,T2>::~PTR () {                   \
324     DEC_COUNT_NULL (this->rep); }                                         \
325   template<TT1 T1, TT2 T2> PTR##_rep<T1,T2>* PTR<T1,T2>::operator -> () { \
326     return this->rep; }                                                   \
327   template<TT1 T1, TT2 T2>                                                \
328   inline PTR<T1,T2>& PTR<T1,T2>::operator = (PTR<T1,T2> x) {              \
329     INC_COUNT_NULL (x.rep); DEC_COUNT_NULL (this->rep);                   \
330     this->rep=x.rep; return *this; }                                      \
331   template<TT1 T1, TT2 T2> inline bool is_nil (PTR<T1,T2> x) {               \
332     return x.rep==NULL; }
333 // end concrete_null
334 
335 // abstract_null
336 #define ABSTRACT_NULL(PTR) \
337   CONCRETE_NULL (PTR);     \
338   inline PTR (PTR##_rep*)
339 #define ABSTRACT_NULL_CODE(PTR)      \
340   CONCRETE_NULL_CODE (PTR);          \
341   inline PTR::PTR (PTR##_rep* rep2): \
342     rep(rep2) { INC_COUNT_NULL (this->rep); }
343 #define ABSTRACT_NULL_TEMPLATE(PTR,T) \
344   CONCRETE_NULL_TEMPLATE (PTR,T);     \
345   inline PTR (PTR##_rep<T>*)
346 #define ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T)              \
347   CONCRETE_NULL_TEMPLATE_CODE (PTR,TT,T);                  \
348   template<TT T> inline PTR<T>::PTR (PTR##_rep<T>* rep2):  \
349     rep(rep2) { INC_COUNT (this->rep); }
350 #define ABSTRACT_NULL_TEMPLATE_2(PTR,T1,T2) \
351   CONCRETE_NULL_TEMPLATE_2 (PTR,T1,T2);     \
352   inline PTR (PTR##_rep<T1,T2>*)
353 #define ABSTRACT_NULL_TEMPLATE_2_CODE(PTR,TT1,T1,TT2,T2)                    \
354   CONCRETE_NULL_TEMPLATE_2_CODE (PTR,TT1,T1,TT2,T2);                          \
355   template<TT1 T1,TT2 T2> inline PTR<T1,T2>::PTR (PTR##_rep<T1,T2>* rep2):  \
356     rep(rep2) { INC_COUNT (this->rep); }
357 // end abstract_null
358 
359 /******************************************************************************
360 * extensions
361 ******************************************************************************/
362 
363 #define EXTEND(BASE,PTR) \
364   ABSTRACT(PTR);         \
365   inline PTR(BASE&);     \
366   inline operator BASE ()
367 #define EXTEND_CODE(BASE,PTR)             \
368   ABSTRACT_CODE(PTR);                     \
369   inline PTR::PTR(BASE& x):               \
370     rep(static_cast<PTR##_rep*>(x.rep)) { \
371     INC_COUNT (this->rep); }              \
372   inline PTR::operator BASE () { return BASE (this->rep); }
373 // end extend
374 
375 // extend_null
376 #define EXTEND_NULL(BASE,PTR) \
377   ABSTRACT_NULL(PTR);         \
378   inline PTR(BASE&);          \
379   inline operator BASE ()
380 #define EXTEND_NULL_CODE(BASE,PTR)        \
381   ABSTRACT_NULL_CODE(PTR);                \
382   inline PTR::PTR(BASE& x):               \
383     rep(static_cast<PTR##_rep*>(x.rep)) { \
384     INC_COUNT_NULL(this->rep); }          \
385   inline PTR::operator BASE () { return BASE (this->rep); }
386 
387 #define EXTEND_NULL_TEMPLATE(BASE,PTR,T) \
388   ABSTRACT_NULL_TEMPLATE(PTR,T);         \
389   inline PTR<T>(BASE&);                  \
390   inline operator BASE ()
391 #define EXTEND_NULL_TEMPLATE_CODE(BASE,PTR,TT,T) \
392   ABSTRACT_NULL_TEMPLATE_CODE(PTR,TT,T);         \
393   template<TT T> inline PTR<T>::PTR(BASE& x):    \
394     rep(static_cast<PTR##_rep<T>*>(x.rep)) {     \
395     INC_COUNT_NULL(this->rep); }                 \
396   template<TT T> inline PTR<T>::operator BASE () { return BASE (this->rep); }
397 // end extend_null
398 
399 #endif // defined BASIC_H
400