FORM v5.0.0-35-g6318119
form3.h
Go to the documentation of this file.
1
8/* #[ License : */
9/*
10 * Copyright (C) 1984-2026 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 5
48#define MINORVERSION 0
49#define PATCHVERSION 0
50
51#ifdef __DATE__
52#define PRODUCTIONDATE __DATE__
53#else
54#define PRODUCTIONDATE "27-jan-2026"
55#endif
56
57#undef BETAVERSION
58/*#define BETAVERSION*/
59
60#ifdef LINUX32
61#define UNIX
62#define LINUX
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 WITHZLIB
73#define WITHGMP
74#define WITHPOSIXCLOCK
75#define WITHFLOAT
76#endif
77
78#ifdef APPLE32
79#define UNIX
80#define _FILE_OFFSET_BITS 64
81#define WITHZLIB
82#endif
83
84#ifdef APPLE64
85#define UNIX
86#define WITHZLIB
87#define WITHGMP
88#define WITHPOSIXCLOCK
89#define WITHFLOAT
90#define HAVE_UNORDERED_MAP
91#define HAVE_UNORDERED_SET
92#endif
93
94#ifdef CYGWIN32
95#define UNIX
96#endif
97
98#ifdef _MSC_VER
99#define WINDOWS
100#define _CRT_SECURE_NO_WARNINGS
101#endif
102
103/*
104 * We must not define WITHPOSIXCLOCK in compiling the sequential FORM or ParFORM.
105 */
106#if !defined(WITHPTHREADS) && defined(WITHPOSIXCLOCK)
107#undef WITHPOSIXCLOCK
108#endif
109
110#if !defined(__cplusplus) && !defined(inline)
111#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
112/* "inline" is available. */
113#elif defined(__GNUC__)
114/* GNU C compiler has "__inline__". */
115#define inline __inline__
116#elif defined(_MSC_VER)
117/* Microsoft C compiler has "__inline". */
118#define inline __inline
119#else
120/* Inline functions may be not supported. Define "inline" to be empty. */
121#define inline
122#endif
123#endif
124
125#endif /* HAVE_CONFIG_H */
126
127/* Workaround for MSVC. */
128#if defined(_MSC_VER)
129/*
130 * Old versions of MSVC didn't support C99 function `snprintf`, which is used
131 * in poly.cc. On the other hand, macroizing `snprintf` gives a fatal error
132 * with MSVC >= 2015.
133 */
134#if _MSC_VER < 1900
135#define snprintf _snprintf
136#endif
137#endif
138
139/*
140 * Translate our dialect "DEBUGGING" to the standard "NDEBUG".
141 */
142#ifdef DEBUGGING
143#ifdef NDEBUG
144#undef NDEBUG
145#endif
146#else
147#ifndef NDEBUG
148#define NDEBUG
149#endif
150#endif
151
152/*
153 * STATIC_ASSERT(condition) will fail to be compiled if the given
154 * condition is false.
155 */
156/*
157#define STATIC_ASSERT(condition)
158*/
159#define STATIC_ASSERT(condition) STATIC_ASSERT__1(condition,__LINE__)
160#define STATIC_ASSERT__1(X,L) STATIC_ASSERT__2(X,L)
161#define STATIC_ASSERT__2(X,L) STATIC_ASSERT__3(X,L)
162#define STATIC_ASSERT__3(X,L) \
163 typedef char static_assertion_failed_##L[(!!(X))*2-1]
164
165/*
166 * UNIX or WINDOWS must be defined.
167 */
168#if defined(UNIX)
169#define mBSD
170#define ANSI
171#elif defined(WINDOWS)
172#define ANSI
173#define WIN32_LEAN_AND_MEAN
174#include <windows.h>
175#include <io.h>
176#include <fcntl.h>
177/* Undefine/rename conflicted symbols. */
178#undef MAXLONG /* WinNT.h */
179#define WORD FORM_WORD /* WinDef.h */
180#define LONG FORM_LONG /* WinNT.h */
181#define ULONG FORM_ULONG /* WinDef.h */
182#define BOOL FORM_BOOL /* WinDef.h */
183#undef CreateFile /* WinBase.h */
184#undef CopyFile /* WinBase.h */
185#define OpenFile FORM_OpenFile /* WinBase.h */
186#define ReOpenFile FORM_ReOpenFile /* WinBase.h */
187#define ReadFile FORM_ReadFile /* WinBase.h */
188#define WriteFile FORM_WriteFile /* WinBase.h */
189#define DeleteObject FORM_DeleteObject /* WinGDI.h */
190#else
191#error UNIX or WINDOWS must be defined!
192#endif
193
194#include <stdint.h>
195
196#if UINTPTR_MAX == UINT64_MAX
197 typedef int32_t WORD;
198 typedef int64_t LONG;
199 typedef uint32_t UWORD;
200 typedef uint64_t ULONG;
201 #define BITSINWORD 32
202 #define BITSINLONG 64
203 #define WORD_MIN_VALUE INT32_MIN
204 #define WORD_MAX_VALUE INT32_MAX
205 #define LONG_MIN_VALUE INT64_MIN
206 #define LONG_MAX_VALUE INT64_MAX
207#elif UINTPTR_MAX == UINT32_MAX
208 typedef int16_t WORD;
209 typedef int32_t LONG;
210 typedef uint16_t UWORD;
211 typedef uint32_t ULONG;
212 #define BITSINWORD 16
213 #define BITSINLONG 32
214 #define WORD_MIN_VALUE INT16_MIN
215 #define WORD_MAX_VALUE INT16_MAX
216 #define LONG_MIN_VALUE INT32_MIN
217 #define LONG_MAX_VALUE INT32_MAX
218#else
219 #error Can not detect if this is a 32-bit or 64-bit platform.
220#endif
221
222STATIC_ASSERT(sizeof(WORD) * 8 == BITSINWORD);
223STATIC_ASSERT(sizeof(LONG) * 8 == BITSINLONG);
224STATIC_ASSERT(sizeof(WORD) * 2 == sizeof(LONG));
225STATIC_ASSERT(sizeof(LONG) >= sizeof(int *));
226STATIC_ASSERT(sizeof(LONG) >= sizeof(int *));
227STATIC_ASSERT(sizeof(int *) >= sizeof(int));
228STATIC_ASSERT(sizeof(int) >= sizeof(WORD));
229STATIC_ASSERT(sizeof(WORD) >= sizeof(char));
230STATIC_ASSERT(sizeof(char) == 1);
231
232typedef signed char SBYTE;
233typedef unsigned char UBYTE;
234typedef unsigned int UINT;
235typedef ULONG RLONG; /* Used in reken.c. */
236typedef int64_t MLONG; /* See commentary in minos.h. */
237/*
238 * NOTE: we don't use the standard _Bool (or C++ bool) because its size is
239 * implementation-dependent.
240 */
241typedef char BOOL;
242 /* E.g. in 32-bits */
243#define TOPBITONLY ((ULONG)1 << (BITSINWORD - 1)) /* 0x00008000UL */
244#define TOPLONGBITONLY ((ULONG)1 << (BITSINLONG - 1)) /* 0x80000000UL */
245#define SPECMASK ((UWORD)1 << (BITSINWORD - 1)) /* 0x8000U */
246#define WILDMASK ((UWORD)1 << (BITSINWORD - 2)) /* 0x4000U */
247#define WORDMASK ((ULONG)FULLMAX - 1) /* 0x0000FFFFUL */
248#define AWORDMASK (WORDMASK << BITSINWORD) /* 0xFFFF0000UL */
249#define FULLMAX ((LONG)1 << BITSINWORD) /* 0x00010000L */
250#define MAXPOSITIVE ((LONG)(TOPBITONLY - 1)) /* 0x00007FFFL */
251#define MAXLONG ((LONG)(TOPLONGBITONLY - 1)) /* 0x7FFFFFFFL */
252#define MAXPOSITIVE2 (MAXPOSITIVE / 2) /* 0x00003FFFL */
253#define MAXPOSITIVE4 (MAXPOSITIVE / 4) /* 0x00001FFFL */
254
255/*
256 * form_alignof(type) returns the number of bytes used in the alignment of
257 * the type.
258 */
259#if !defined(form_alignof)
260#if defined(__GNUC__)
261/* GNU C compiler has "__alignof__". */
262#define form_alignof(type) __alignof__(type)
263#elif defined(_MSC_VER)
264/* Microsoft C compiler has "__alignof". */
265#define form_alignof(type) __alignof(type)
266#elif !defined(__cplusplus)
267/* Generic case in C. */
268#include <stddef.h>
269#define form_alignof(type) offsetof(struct { char c_; type x_; }, x_)
270#else
271/* Generic case in C++, at least works with a POD struct. */
272#include <cstddef>
273namespace alignof_impl_ {
274template<typename T> struct calc {
275 struct X { char c_; T x_; };
276 enum { value = offsetof(X, x_) };
277};
278}
279#define form_alignof(type) alignof_impl_::calc<type>::value
280#endif
281#endif
282
283
284/*
285#define WITHPCOUNTER
286#define DEBUGGINGLOCKS
287#define WITHSTATS
288*/
289#define WITHSORTBOTS
290
291#include <stdio.h>
292#include <stdlib.h>
293#include <string.h>
294#include <ctype.h>
295#include <limits.h>
296#include <stdarg.h>
297#include <time.h>
298#ifdef WINDOWS
299#include "fwin.h"
300#endif
301#ifdef UNIX
302#include <unistd.h>
303#include <fcntl.h>
304#include <sys/file.h>
305#include "unix.h"
306#endif
307#ifdef WITHZLIB
308#ifdef WITHZSTD
309#include <zstd_zlibwrapper.h>
310#else
311#include <zlib.h>
312#endif
313#endif
314#ifdef WITHPTHREADS
315#include <pthread.h>
316#endif
317
318/*
319 PARALLELCODE indicates code that is common for TFORM and ParFORM but
320 should not be there for sequential FORM.
321*/
322#if defined(WITHMPI) || defined(WITHPTHREADS)
323#define PARALLELCODE
324#endif
325
326#include "ftypes.h"
327#include "fsizes.h"
328#include "minos.h"
329#include "structs.h"
330#include "declare.h"
331#include "variable.h"
332
333STATIC_ASSERT(sizeof(off_t) >= sizeof(LONG));
334
335/*
336 * The interface to file routines for UNIX or non-UNIX (Windows).
337 */
338#ifdef UNIX
339
340#define UFILES
341typedef struct FiLeS {
342 int descriptor;
343} FILES;
344extern FILES *Uopen(char *,char *);
345extern int Uclose(FILES *);
346extern size_t Uread(char *,size_t,size_t,FILES *);
347extern size_t Uwrite(char *,size_t,size_t,FILES *);
348extern int Useek(FILES *,off_t,int);
349extern off_t Utell(FILES *);
350extern void Uflush(FILES *);
351extern int Ugetpos(FILES *,fpos_t *);
352extern int Usetpos(FILES *,fpos_t *);
353extern void Usetbuf(FILES *,char *);
354#define Usync(f) fsync(f->descriptor)
355#define Utruncate(f) { \
356 if ( ftruncate(f->descriptor, 0) ) { \
357 MLOCK(ErrorMessageLock); \
358 MesPrint("Utruncate failed"); \
359 MUNLOCK(ErrorMessageLock); \
360 /* Calling Terminate() here may cause an infinite loop due to CleanUpSort(). */ \
361 /* Terminate(-1); */ \
362 } \
363}
364extern FILES *Ustdout;
365#define MAX_OPEN_FILES getdtablesize()
366#define GetPID() ((LONG)getpid())
367
368#else /* UNIX */
369
370#define FILES FILE
371#define Uopen(x,y) fopen(x,y)
372#define Uflush(x) fflush(x)
373#define Uclose(x) fclose(x)
374#define Uread(x,y,z,u) fread(x,y,z,u)
375#define Uwrite(x,y,z,u) fwrite(x,y,z,u)
376#define Usetbuf(x,y) setbuf(x,y)
377#define Useek(x,y,z) fseek(x,y,z)
378#define Utell(x) ftell(x)
379#define Ugetpos(x,y) fgetpos(x,y)
380#define Usetpos(x,y) fsetpos(x,y)
381#define Usync(x) fflush(x)
382#define Utruncate(x) _chsize(_fileno(x),0)
383#define Ustdout stdout
384#define MAX_OPEN_FILES FOPEN_MAX
385#define bzero(b,len) (memset((b), 0, (len)), (void)0)
386#define GetPID() ((LONG)GetCurrentProcessId())
387
388#endif /* UNIX */
389
390/*
391 * Some system may implement the POSIX "environ" variable as a macro, e.g.,
392 * https://github.com/mingw-w64/mingw-w64/blob/v10.0.0/mingw-w64-headers/crt/stdlib.h#L704
393 * which breaks the definition of DoShattering() in diagrams.c that uses
394 * "environ" as a formal parameter. Because FORM doesn't use the POSIX "environ"
395 * or its variant anyway, we can just undefine it.
396 */
397#ifdef environ
398#undef environ
399#endif
400
401#ifdef WITHMPI
402#include "parallel.h"
403#endif
404
405#endif /* __FORM3H__ */