FORM  4.2
form3.h
Go to the documentation of this file.
1 
8 /* #[ License : */
9 /*
10  * Copyright (C) 1984-2017 J.A.M. Vermaseren
11  * When using this file you are requested to refer to the publication
12  * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
13  * This is considered a matter of courtesy as the development was paid
14  * for by FOM the Dutch physics granting agency and we would like to
15  * be able to track its scientific use to convince FOM of its value
16  * for the community.
17  *
18  * This file is part of FORM.
19  *
20  * FORM is free software: you can redistribute it and/or modify it under the
21  * terms of the GNU General Public License as published by the Free Software
22  * Foundation, either version 3 of the License, or (at your option) any later
23  * version.
24  *
25  * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
26  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
28  * details.
29  *
30  * You should have received a copy of the GNU General Public License along
31  * with FORM. If not, see <http://www.gnu.org/licenses/>.
32  */
33 /* #] License : */
34 
35 #ifndef __FORM3H__
36 #define __FORM3H__
37 
38 #ifdef HAVE_CONFIG_H
39 
40 #ifndef CONFIG_H_INCLUDED
41 #define CONFIG_H_INCLUDED
42 #include <config.h>
43 #endif
44 
45 #else /* HAVE_CONFIG_H */
46 
47 #define MAJORVERSION 4
48 #define MINORVERSION 2
49 
50 #ifdef __DATE__
51 #define PRODUCTIONDATE 20170706
52 #else
53 #define PRODUCTIONDATE "06-jul-2017"
54 #endif
55 
56 #undef BETAVERSION
57 
58 #ifdef LINUX32
59 #define UNIX
60 #define LINUX
61 #define ILP32
62 #define SIZEOF_LONG_LONG 8
63 #define _FILE_OFFSET_BITS 64
64 #define WITHZLIB
65 #define WITHGMP
66 #define WITHPOSIXCLOCK
67 #endif
68 
69 #ifdef LINUX64
70 #define UNIX
71 #define LINUX
72 #define LP64
73 #define WITHZLIB
74 #define WITHGMP
75 #define WITHPOSIXCLOCK
76 #endif
77 
78 #ifdef APPLE32
79 #define UNIX
80 #define ILP32
81 #define SIZEOF_LONG_LONG 8
82 #define _FILE_OFFSET_BITS 64
83 #define WITHZLIB
84 #endif
85 
86 #ifdef APPLE64
87 #define UNIX
88 #define LP64
89 #define WITHZLIB
90 #define WITHGMP
91 #define WITHPOSIXCLOCK
92 #endif
93 
94 #ifdef CYGWIN32
95 #define UNIX
96 #define ILP32
97 #define SIZEOF_LONG_LONG 8
98 #endif
99 
100 #ifdef _MSC_VER
101 #define WINDOWS
102 #define _CRT_SECURE_NO_WARNINGS
103 #if defined(_WIN64)
104 #define LLP64
105 #elif defined(_WIN32)
106 #define ILP32
107 #define SIZEOF_LONG_LONG 8
108 #endif
109 #endif
110 
111 /*
112  * We must not define WITHPOSIXCLOCK in compiling the sequential FORM or ParFORM.
113  */
114 #if !defined(WITHPTHREADS) && defined(WITHPOSIXCLOCK)
115 #undef WITHPOSIXCLOCK
116 #endif
117 
118 #if !defined(__cplusplus) && !defined(inline)
119 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
120 /* "inline" is available. */
121 #elif defined(__GNUC__)
122 /* GNU C compiler has "__inline__". */
123 #define inline __inline__
124 #elif defined(_MSC_VER)
125 /* Microsoft C compiler has "__inline". */
126 #define inline __inline
127 #else
128 /* Inline functions may be not supported. Define "inline" to be empty. */
129 #define inline
130 #endif
131 #endif
132 
133 #endif /* HAVE_CONFIG_H */
134 
135 /* Workaround for MSVC. */
136 #if defined(_MSC_VER)
137 /*
138  * Recent versions of MSVC++ (>= 2012) don't like reserved keywords being
139  * macroized even when they are not available. This is problematic for
140  * `alignof`, which is used in legacy `PADXXX` macros. We disable tests in
141  * xkeycheck.h.
142  */
143 #if _MSC_VER >= 1700
144 #define _ALLOW_KEYWORD_MACROS
145 #endif
146 /*
147  * Old versions of MSVC didn't support C99 function `snprintf`, which is used
148  * in poly.cc. On the other hand, macroizing `snprintf` gives a fatal error
149  * with MSVC >= 2015.
150  */
151 #if _MSC_VER < 1900
152 #define snprintf _snprintf
153 #endif
154 #endif
155 
156 /*
157  * Translate our dialect "DEBUGGING" to the standard "NDEBUG".
158  */
159 #ifdef DEBUGGING
160 #ifdef NDEBUG
161 #undef NDEBUG
162 #endif
163 #else
164 #ifndef NDEBUG
165 #define NDEBUG
166 #endif
167 #endif
168 
169 /*
170  * STATIC_ASSERT(condition) will fail to be compiled if the given
171  * condition is false.
172  */
173 #define STATIC_ASSERT(condition) STATIC_ASSERT__1(condition,__LINE__)
174 #define STATIC_ASSERT__1(X,L) STATIC_ASSERT__2(X,L)
175 #define STATIC_ASSERT__2(X,L) STATIC_ASSERT__3(X,L)
176 #define STATIC_ASSERT__3(X,L) \
177  typedef char static_assertion_failed_##L[(!!(X))*2-1]
178 
179 /*
180  * UNIX or WINDOWS must be defined.
181  */
182 #if defined(UNIX)
183 #define mBSD
184 #define ANSI
185 #elif defined(WINDOWS)
186 #define ANSI
187 #define WIN32_LEAN_AND_MEAN
188 #include <windows.h>
189 #include <io.h>
190 /* Undefine/rename conflicted symbols. */
191 #undef VOID /* WinNT.h */
192 #undef MAXLONG /* WinNT.h */
193 #define WORD FORM_WORD /* WinDef.h */
194 #define LONG FORM_LONG /* WinNT.h */
195 #define ULONG FORM_ULONG /* WinDef.h */
196 #undef CreateFile /* WinBase.h */
197 #undef CopyFile /* WinBase.h */
198 #define OpenFile FORM_OpenFile /* WinBase.h */
199 #define ReOpenFile FORM_ReOpenFile /* WinBase.h */
200 #define ReadFile FORM_ReadFile /* WinBase.h */
201 #define WriteFile FORM_WriteFile /* WinBase.h */
202 #define DeleteObject FORM_DeleteObject /* WinGDI.h */
203 #else
204 #error UNIX or WINDOWS must be defined!
205 #endif
206 
207 /*
208  * Data model. ILP32 or LLP64 or LP64 must be defined.
209  *
210  * Here we define basic types WORD, LONG and their unsigned versions
211  * UWORD and ULONG. LONG must be double size of WORD. Their actual types
212  * are system-dependent. BITSINWORD and BITSINLONG are also defined.
213  * INT16, INT32 (also INT64 and INT128 if available) are used for
214  * system independent saved expressions (store.c).
215  */
216 #if defined(ILP32)
217 
218 typedef short WORD;
219 typedef long LONG;
220 typedef unsigned short UWORD;
221 typedef unsigned long ULONG;
222 #define BITSINWORD 16
223 #define BITSINLONG 32
224 #define INT16 short
225 #define INT32 int
226 #undef INT64
227 #undef INT128
228 
229 #ifdef SIZEOF_LONG_LONG
230 #if SIZEOF_LONG_LONG == 8
231 #define INT64 long long
232 #endif
233 #endif
234 
235 #ifndef INT64
236 #error INT64 is not available!
237 #endif
238 
239 #elif defined(LLP64)
240 
241 typedef int WORD;
242 typedef long long LONG;
243 typedef unsigned int UWORD;
244 typedef unsigned long long ULONG;
245 #define BITSINWORD 32
246 #define BITSINLONG 64
247 #define INT16 short
248 #define INT32 int
249 #define INT64 long long
250 #undef INT128
251 
252 #elif defined(LP64)
253 
254 typedef int WORD;
255 typedef long LONG;
256 typedef unsigned int UWORD;
257 typedef unsigned long ULONG;
258 #define BITSINWORD 32
259 #define BITSINLONG 64
260 #define INT16 short
261 #define INT32 int
262 #define INT64 long
263 #undef INT128
264 
265 #else
266 #error ILP32 or LLP64 or LP64 must be defined!
267 #endif
268 
269 STATIC_ASSERT(sizeof(WORD) * 8 == BITSINWORD);
270 STATIC_ASSERT(sizeof(LONG) * 8 == BITSINLONG);
271 STATIC_ASSERT(sizeof(WORD) * 2 == sizeof(LONG));
272 STATIC_ASSERT(sizeof(LONG) >= sizeof(int *));
273 STATIC_ASSERT(sizeof(INT16) == 2);
274 STATIC_ASSERT(sizeof(INT32) == 4);
275 STATIC_ASSERT(sizeof(INT64) == 8);
276 #ifdef INT128
277 STATIC_ASSERT(sizeof(INT128) == 16);
278 #endif
279 
280 #if BITSINWORD == 32
281 #define WORDSIZE32 1
282 #endif
283 
284 typedef void VOID;
285 typedef signed char SBYTE;
286 typedef unsigned char UBYTE;
287 typedef unsigned int UINT;
288 typedef ULONG RLONG; /* Used in reken.c. */
289 typedef INT64 MLONG; /* See commentary in minos.h. */
290  /* E.g. in 32-bits */
291 #define TOPBITONLY ((ULONG)1 << (BITSINWORD - 1)) /* 0x00008000UL */
292 #define TOPLONGBITONLY ((ULONG)1 << (BITSINLONG - 1)) /* 0x80000000UL */
293 #define SPECMASK ((UWORD)1 << (BITSINWORD - 1)) /* 0x8000U */
294 #define WILDMASK ((UWORD)1 << (BITSINWORD - 2)) /* 0x4000U */
295 #define WORDMASK ((ULONG)FULLMAX - 1) /* 0x0000FFFFUL */
296 #define AWORDMASK (WORDMASK << BITSINWORD) /* 0xFFFF0000UL */
297 #define FULLMAX ((LONG)1 << BITSINWORD) /* 0x00010000L */
298 #define MAXPOSITIVE ((LONG)(TOPBITONLY - 1)) /* 0x00007FFFL */
299 #define MAXLONG ((LONG)(TOPLONGBITONLY - 1)) /* 0x7FFFFFFFL */
300 #define MAXPOSITIVE2 (MAXPOSITIVE / 2) /* 0x00003FFFL */
301 #define MAXPOSITIVE4 (MAXPOSITIVE / 4) /* 0x00001FFFL */
302 
303 /*
304  * alignof(type) returns the number of bytes used in the alignment of
305  * the type.
306  */
307 #if !defined(alignof)
308 #if defined(__GNUC__)
309 /* GNU C compiler has "__alignof__". */
310 #define alignof(type) __alignof__(type)
311 #elif defined(_MSC_VER)
312 /* Microsoft C compiler has "__alignof". */
313 #define alignof(type) __alignof(type)
314 #elif !defined(__cplusplus)
315 /* Generic case in C. */
316 #include <stddef.h>
317 #define alignof(type) offsetof(struct { char c_; type x_; }, x_)
318 #else
319 /* Generic case in C++, at least works with a POD struct. */
320 #include <cstddef>
321 namespace alignof_impl_ {
322 template<typename T> struct calc {
323  struct X { char c_; T x_; };
324  enum { value = offsetof(X, x_) };
325 };
326 }
327 #define alignof(type) alignof_impl_::calc<type>::value
328 #endif
329 #endif
330 
331 /*
332  * Macros inserted to the end of a structure to align the whole structure.
333  *
334  * In the currently available systems,
335  * sizeof(POSITION) >= sizeof(pointers) == sizeof(LONG) >= sizeof(int)
336  * >= sizeof(WORD) >= sizeof(UBYTE) = 1.
337  * (POSITION is defined in struct.h and contains only an off_t variable.)
338  * Thus, if we put members of a structure in this order and use those macros,
339  * then we can align the data without relying on extra paddings added by
340  * the compiler. For example,
341  * typedef struct {
342  * int *a;
343  * LONG b;
344  * WORD c[2];
345  * UBYTE d;
346  * PADPOINTER(1,0,2,1);
347  * } A;
348  * typedef struct {
349  * POSITION p;
350  * A a; // aligned same as pointers
351  * int *b;
352  * LONG c;
353  * UBYTE d;
354  * PADPOSITION(1,1,0,0,1+sizeof(A));
355  * } B;
356  * The cost for the use of those PADXXX functions is a padding (>= 1 byte) will
357  * be always inserted even in the case that no padding is actually needed.
358  *
359  * Note that there is a 32-bit system in which off_t is aligned on 8-byte
360  * boundary, (e.g., Cygwin).
361  */
362 #define PADDUMMY(type, size) \
363  UBYTE d_u_m_m_y[alignof(type) - ((size) & (alignof(type) - 1))]
364 #define PADPOSITION(ptr_,long_,int_,word_,byte_) \
365  PADDUMMY(off_t, \
366  + sizeof(int *) * (ptr_) \
367  + sizeof(LONG) * (long_) \
368  + sizeof(int) * (int_) \
369  + sizeof(WORD) * (word_) \
370  + sizeof(UBYTE) * (byte_) \
371  )
372 #define PADPOINTER(long_,int_,word_,byte_) \
373  PADDUMMY(int *, \
374  + sizeof(LONG) * (long_) \
375  + sizeof(int) * (int_) \
376  + sizeof(WORD) * (word_) \
377  + sizeof(UBYTE) * (byte_) \
378  )
379 #define PADLONG(int_,word_,byte_) \
380  PADDUMMY(LONG, \
381  + sizeof(int) * (int_) \
382  + sizeof(WORD) * (word_) \
383  + sizeof(UBYTE) * (byte_) \
384  )
385 #define PADINT(word_,byte_) \
386  PADDUMMY(int, \
387  + sizeof(WORD) * (word_) \
388  + sizeof(UBYTE) * (byte_) \
389  )
390 #define PADWORD(byte_) \
391  PADDUMMY(WORD, \
392  + sizeof(UBYTE) * (byte_) \
393  )
394 
395 /*
396 #define WITHPCOUNTER
397 #define DEBUGGINGLOCKS
398 #define WITHSTATS
399 */
400 #define WITHSORTBOTS
401 
402 #include <stdio.h>
403 #include <stdlib.h>
404 #include <string.h>
405 #include <ctype.h>
406 #ifdef ANSI
407 #include <stdarg.h>
408 #include <time.h>
409 #endif
410 #ifdef WINDOWS
411 #include "fwin.h"
412 #endif
413 #ifdef UNIX
414 #include <unistd.h>
415 #include <time.h>
416 #include <fcntl.h>
417 #include <sys/file.h>
418 #include "unix.h"
419 #endif
420 #ifdef WITHZLIB
421 #include <zlib.h>
422 #endif
423 #ifdef WITHPTHREADS
424 #include <pthread.h>
425 #endif
426 
427 /*
428  PARALLELCODE indicates code that is common for TFORM and ParFORM but
429  should not be there for sequential FORM.
430 */
431 #if defined(WITHMPI) || defined(WITHPTHREADS)
432 #define PARALLELCODE
433 #endif
434 
435 #include "ftypes.h"
436 #include "fsizes.h"
437 #include "minos.h"
438 #include "structs.h"
439 #include "declare.h"
440 #include "variable.h"
441 
442 /*
443  * The interface to file routines for UNIX or non-UNIX (Windows).
444  */
445 #ifdef UNIX
446 
447 #define UFILES
448 typedef struct FiLeS {
449  int descriptor;
450 } FILES;
451 extern FILES *Uopen(char *,char *);
452 extern int Uclose(FILES *);
453 extern size_t Uread(char *,size_t,size_t,FILES *);
454 extern size_t Uwrite(char *,size_t,size_t,FILES *);
455 extern int Useek(FILES *,off_t,int);
456 extern off_t Utell(FILES *);
457 extern void Uflush(FILES *);
458 extern int Ugetpos(FILES *,fpos_t *);
459 extern int Usetpos(FILES *,fpos_t *);
460 extern void Usetbuf(FILES *,char *);
461 #define Usync(f) fsync(f->descriptor)
462 #define Utruncate(f) { \
463  if ( ftruncate(f->descriptor, 0) ) { \
464  MLOCK(ErrorMessageLock); \
465  MesPrint("Utruncate failed"); \
466  MUNLOCK(ErrorMessageLock); \
467  /* Calling Terminate() here may cause an infinite loop due to CleanUpSort(). */ \
468  /* Terminate(-1); */ \
469  } \
470 }
471 extern FILES *Ustdout;
472 #define MAX_OPEN_FILES getdtablesize()
473 #define GetPID() ((LONG)getpid())
474 
475 #else /* UNIX */
476 
477 #define FILES FILE
478 #define Uopen(x,y) fopen(x,y)
479 #define Uflush(x) fflush(x)
480 #define Uclose(x) fclose(x)
481 #define Uread(x,y,z,u) fread(x,y,z,u)
482 #define Uwrite(x,y,z,u) fwrite(x,y,z,u)
483 #define Usetbuf(x,y) setbuf(x,y)
484 #define Useek(x,y,z) fseek(x,y,z)
485 #define Utell(x) ftell(x)
486 #define Ugetpos(x,y) fgetpos(x,y)
487 #define Usetpos(x,y) fsetpos(x,y)
488 #define Usync(x) fflush(x)
489 #define Utruncate(x) _chsize(_fileno(x),0)
490 #define Ustdout stdout
491 #define MAX_OPEN_FILES FOPEN_MAX
492 #define bzero(b,len) (memset((b), 0, (len)), (void)0)
493 #define GetPID() ((LONG)GetCurrentProcessId())
494 
495 #endif /* UNIX */
496 
497 #ifdef WITHMPI
498 #include "parallel.h"
499 #endif
500 
501 #endif /* __FORM3H__ */