1 /** @file form3.h 2 * 3 * Contains critical defines for the compilation process 4 * Also contains the inclusion of all necessary header files. 5 * There are also some system dependencies concerning file functions. 6 */ 7 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 __DATE__ 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 #define HAVE_UNORDERED_MAP 93 #define HAVE_UNORDERED_SET 94 #endif 95 96 #ifdef CYGWIN32 97 #define UNIX 98 #define ILP32 99 #define SIZEOF_LONG_LONG 8 100 #endif 101 102 #ifdef _MSC_VER 103 #define WINDOWS 104 #define _CRT_SECURE_NO_WARNINGS 105 #if defined(_WIN64) 106 #define LLP64 107 #elif defined(_WIN32) 108 #define ILP32 109 #define SIZEOF_LONG_LONG 8 110 #endif 111 #endif 112 113 /* 114 * We must not define WITHPOSIXCLOCK in compiling the sequential FORM or ParFORM. 115 */ 116 #if !defined(WITHPTHREADS) && defined(WITHPOSIXCLOCK) 117 #undef WITHPOSIXCLOCK 118 #endif 119 120 #if !defined(__cplusplus) && !defined(inline) 121 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) 122 /* "inline" is available. */ 123 #elif defined(__GNUC__) 124 /* GNU C compiler has "__inline__". */ 125 #define inline __inline__ 126 #elif defined(_MSC_VER) 127 /* Microsoft C compiler has "__inline". */ 128 #define inline __inline 129 #else 130 /* Inline functions may be not supported. Define "inline" to be empty. */ 131 #define inline 132 #endif 133 #endif 134 135 #endif /* HAVE_CONFIG_H */ 136 137 /* Workaround for MSVC. */ 138 #if defined(_MSC_VER) 139 /* 140 * Recent versions of MSVC++ (>= 2012) don't like reserved keywords being 141 * macroized even when they are not available. This is problematic for 142 * `alignof`, which is used in legacy `PADXXX` macros. We disable tests in 143 * xkeycheck.h. 144 */ 145 #if _MSC_VER >= 1700 146 #define _ALLOW_KEYWORD_MACROS 147 #endif 148 /* 149 * Old versions of MSVC didn't support C99 function `snprintf`, which is used 150 * in poly.cc. On the other hand, macroizing `snprintf` gives a fatal error 151 * with MSVC >= 2015. 152 */ 153 #if _MSC_VER < 1900 154 #define snprintf _snprintf 155 #endif 156 #endif 157 158 /* 159 * Translate our dialect "DEBUGGING" to the standard "NDEBUG". 160 */ 161 #ifdef DEBUGGING 162 #ifdef NDEBUG 163 #undef NDEBUG 164 #endif 165 #else 166 #ifndef NDEBUG 167 #define NDEBUG 168 #endif 169 #endif 170 171 /* 172 * STATIC_ASSERT(condition) will fail to be compiled if the given 173 * condition is false. 174 */ 175 #define STATIC_ASSERT(condition) STATIC_ASSERT__1(condition,__LINE__) 176 #define STATIC_ASSERT__1(X,L) STATIC_ASSERT__2(X,L) 177 #define STATIC_ASSERT__2(X,L) STATIC_ASSERT__3(X,L) 178 #define STATIC_ASSERT__3(X,L) \ 179 typedef char static_assertion_failed_##L[(!!(X))*2-1] 180 181 /* 182 * UNIX or WINDOWS must be defined. 183 */ 184 #if defined(UNIX) 185 #define mBSD 186 #define ANSI 187 #elif defined(WINDOWS) 188 #define ANSI 189 #define WIN32_LEAN_AND_MEAN 190 #include <windows.h> 191 #include <io.h> 192 /* Undefine/rename conflicted symbols. */ 193 #undef VOID /* WinNT.h */ 194 #undef MAXLONG /* WinNT.h */ 195 #define WORD FORM_WORD /* WinDef.h */ 196 #define LONG FORM_LONG /* WinNT.h */ 197 #define ULONG FORM_ULONG /* WinDef.h */ 198 #undef CreateFile /* WinBase.h */ 199 #undef CopyFile /* WinBase.h */ 200 #define OpenFile FORM_OpenFile /* WinBase.h */ 201 #define ReOpenFile FORM_ReOpenFile /* WinBase.h */ 202 #define ReadFile FORM_ReadFile /* WinBase.h */ 203 #define WriteFile FORM_WriteFile /* WinBase.h */ 204 #define DeleteObject FORM_DeleteObject /* WinGDI.h */ 205 #else 206 #error UNIX or WINDOWS must be defined! 207 #endif 208 209 /* 210 * Data model. ILP32 or LLP64 or LP64 must be defined. 211 * 212 * Here we define basic types WORD, LONG and their unsigned versions 213 * UWORD and ULONG. LONG must be double size of WORD. Their actual types 214 * are system-dependent. BITSINWORD and BITSINLONG are also defined. 215 * INT16, INT32 (also INT64 and INT128 if available) are used for 216 * system independent saved expressions (store.c). 217 */ 218 #if defined(ILP32) 219 220 typedef short WORD; 221 typedef long LONG; 222 typedef unsigned short UWORD; 223 typedef unsigned long ULONG; 224 #define BITSINWORD 16 225 #define BITSINLONG 32 226 #define INT16 short 227 #define INT32 int 228 #undef INT64 229 #undef INT128 230 231 #ifdef SIZEOF_LONG_LONG 232 #if SIZEOF_LONG_LONG == 8 233 #define INT64 long long 234 #endif 235 #endif 236 237 #ifndef INT64 238 #error INT64 is not available! 239 #endif 240 241 #define WORD_MIN_VALUE SHRT_MIN 242 #define WORD_MAX_VALUE SHRT_MAX 243 #define LONG_MIN_VALUE LONG_MIN 244 #define LONG_MAX_VALUE LONG_MAX 245 246 #elif defined(LLP64) 247 248 typedef int WORD; 249 typedef long long LONG; 250 typedef unsigned int UWORD; 251 typedef unsigned long long ULONG; 252 #define BITSINWORD 32 253 #define BITSINLONG 64 254 #define INT16 short 255 #define INT32 int 256 #define INT64 long long 257 #undef INT128 258 259 #define WORD_MIN_VALUE INT_MIN 260 #define WORD_MAX_VALUE INT_MAX 261 #define LONG_MIN_VALUE LLONG_MIN 262 #define LONG_MAX_VALUE LLONG_MAX 263 264 #elif defined(LP64) 265 266 typedef int WORD; 267 typedef long LONG; 268 typedef unsigned int UWORD; 269 typedef unsigned long ULONG; 270 #define BITSINWORD 32 271 #define BITSINLONG 64 272 #define INT16 short 273 #define INT32 int 274 #define INT64 long 275 #undef INT128 276 277 #define WORD_MIN_VALUE INT_MIN 278 #define WORD_MAX_VALUE INT_MAX 279 #define LONG_MIN_VALUE LONG_MIN 280 #define LONG_MAX_VALUE LONG_MAX 281 282 #else 283 #error ILP32 or LLP64 or LP64 must be defined! 284 #endif 285 286 STATIC_ASSERT(sizeof(WORD) * 8 == BITSINWORD); 287 STATIC_ASSERT(sizeof(LONG) * 8 == BITSINLONG); 288 STATIC_ASSERT(sizeof(WORD) * 2 == sizeof(LONG)); 289 STATIC_ASSERT(sizeof(LONG) >= sizeof(int *)); 290 STATIC_ASSERT(sizeof(INT16) == 2); 291 STATIC_ASSERT(sizeof(INT32) == 4); 292 STATIC_ASSERT(sizeof(INT64) == 8); 293 #ifdef INT128 294 STATIC_ASSERT(sizeof(INT128) == 16); 295 #endif 296 297 #if BITSINWORD == 32 298 #define WORDSIZE32 1 299 #endif 300 301 typedef void VOID; 302 typedef signed char SBYTE; 303 typedef unsigned char UBYTE; 304 typedef unsigned int UINT; 305 typedef ULONG RLONG; /* Used in reken.c. */ 306 typedef INT64 MLONG; /* See commentary in minos.h. */ 307 /* E.g. in 32-bits */ 308 #define TOPBITONLY ((ULONG)1 << (BITSINWORD - 1)) /* 0x00008000UL */ 309 #define TOPLONGBITONLY ((ULONG)1 << (BITSINLONG - 1)) /* 0x80000000UL */ 310 #define SPECMASK ((UWORD)1 << (BITSINWORD - 1)) /* 0x8000U */ 311 #define WILDMASK ((UWORD)1 << (BITSINWORD - 2)) /* 0x4000U */ 312 #define WORDMASK ((ULONG)FULLMAX - 1) /* 0x0000FFFFUL */ 313 #define AWORDMASK (WORDMASK << BITSINWORD) /* 0xFFFF0000UL */ 314 #define FULLMAX ((LONG)1 << BITSINWORD) /* 0x00010000L */ 315 #define MAXPOSITIVE ((LONG)(TOPBITONLY - 1)) /* 0x00007FFFL */ 316 #define MAXLONG ((LONG)(TOPLONGBITONLY - 1)) /* 0x7FFFFFFFL */ 317 #define MAXPOSITIVE2 (MAXPOSITIVE / 2) /* 0x00003FFFL */ 318 #define MAXPOSITIVE4 (MAXPOSITIVE / 4) /* 0x00001FFFL */ 319 320 /* 321 * alignof(type) returns the number of bytes used in the alignment of 322 * the type. 323 */ 324 #if !defined(alignof) 325 #if defined(__GNUC__) 326 /* GNU C compiler has "__alignof__". */ 327 #define alignof(type) __alignof__(type) 328 #elif defined(_MSC_VER) 329 /* Microsoft C compiler has "__alignof". */ 330 #define alignof(type) __alignof(type) 331 #elif !defined(__cplusplus) 332 /* Generic case in C. */ 333 #include <stddef.h> 334 #define alignof(type) offsetof(struct { char c_; type x_; }, x_) 335 #else 336 /* Generic case in C++, at least works with a POD struct. */ 337 #include <cstddef> 338 namespace alignof_impl_ { 339 template<typename T> struct calc { 340 struct X { char c_; T x_; }; 341 enum { value = offsetof(X, x_) }; 342 }; 343 } 344 #define alignof(type) alignof_impl_::calc<type>::value 345 #endif 346 #endif 347 348 /* 349 * Macros inserted to the end of a structure to align the whole structure. 350 * 351 * In the currently available systems, 352 * sizeof(POSITION) >= sizeof(pointers) == sizeof(LONG) >= sizeof(int) 353 * >= sizeof(WORD) >= sizeof(UBYTE) = 1. 354 * (POSITION is defined in struct.h and contains only an off_t variable.) 355 * Thus, if we put members of a structure in this order and use those macros, 356 * then we can align the data without relying on extra paddings added by 357 * the compiler. For example, 358 * typedef struct { 359 * int *a; 360 * LONG b; 361 * WORD c[2]; 362 * UBYTE d; 363 * PADPOINTER(1,0,2,1); 364 * } A; 365 * typedef struct { 366 * POSITION p; 367 * A a; // aligned same as pointers 368 * int *b; 369 * LONG c; 370 * UBYTE d; 371 * PADPOSITION(1,1,0,0,1+sizeof(A)); 372 * } B; 373 * The cost for the use of those PADXXX functions is a padding (>= 1 byte) will 374 * be always inserted even in the case that no padding is actually needed. 375 * 376 * Note that there is a 32-bit system in which off_t is aligned on 8-byte 377 * boundary, (e.g., Cygwin). 378 */ 379 #define PADDUMMY(type, size) \ 380 UBYTE d_u_m_m_y[alignof(type) - ((size) & (alignof(type) - 1))] 381 #define PADPOSITION(ptr_,long_,int_,word_,byte_) \ 382 PADDUMMY(off_t, \ 383 + sizeof(int *) * (ptr_) \ 384 + sizeof(LONG) * (long_) \ 385 + sizeof(int) * (int_) \ 386 + sizeof(WORD) * (word_) \ 387 + sizeof(UBYTE) * (byte_) \ 388 ) 389 #define PADPOINTER(long_,int_,word_,byte_) \ 390 PADDUMMY(int *, \ 391 + sizeof(LONG) * (long_) \ 392 + sizeof(int) * (int_) \ 393 + sizeof(WORD) * (word_) \ 394 + sizeof(UBYTE) * (byte_) \ 395 ) 396 #define PADLONG(int_,word_,byte_) \ 397 PADDUMMY(LONG, \ 398 + sizeof(int) * (int_) \ 399 + sizeof(WORD) * (word_) \ 400 + sizeof(UBYTE) * (byte_) \ 401 ) 402 #define PADINT(word_,byte_) \ 403 PADDUMMY(int, \ 404 + sizeof(WORD) * (word_) \ 405 + sizeof(UBYTE) * (byte_) \ 406 ) 407 #define PADWORD(byte_) \ 408 PADDUMMY(WORD, \ 409 + sizeof(UBYTE) * (byte_) \ 410 ) 411 412 /* 413 #define WITHPCOUNTER 414 #define DEBUGGINGLOCKS 415 #define WITHSTATS 416 */ 417 #define WITHSORTBOTS 418 419 #include <stdio.h> 420 #include <stdlib.h> 421 #include <string.h> 422 #include <ctype.h> 423 #include <limits.h> 424 #ifdef ANSI 425 #include <stdarg.h> 426 #include <time.h> 427 #endif 428 #ifdef WINDOWS 429 #include "fwin.h" 430 #endif 431 #ifdef UNIX 432 #include <unistd.h> 433 #include <time.h> 434 #include <fcntl.h> 435 #include <sys/file.h> 436 #include "unix.h" 437 #endif 438 #ifdef WITHZLIB 439 #include <zlib.h> 440 #endif 441 #ifdef WITHPTHREADS 442 #include <pthread.h> 443 #endif 444 445 /* 446 PARALLELCODE indicates code that is common for TFORM and ParFORM but 447 should not be there for sequential FORM. 448 */ 449 #if defined(WITHMPI) || defined(WITHPTHREADS) 450 #define PARALLELCODE 451 #endif 452 453 #include "ftypes.h" 454 #include "fsizes.h" 455 #include "minos.h" 456 #include "structs.h" 457 #include "declare.h" 458 #include "variable.h" 459 460 /* 461 * The interface to file routines for UNIX or non-UNIX (Windows). 462 */ 463 #ifdef UNIX 464 465 #define UFILES 466 typedef struct FiLeS { 467 int descriptor; 468 } FILES; 469 extern FILES *Uopen(char *,char *); 470 extern int Uclose(FILES *); 471 extern size_t Uread(char *,size_t,size_t,FILES *); 472 extern size_t Uwrite(char *,size_t,size_t,FILES *); 473 extern int Useek(FILES *,off_t,int); 474 extern off_t Utell(FILES *); 475 extern void Uflush(FILES *); 476 extern int Ugetpos(FILES *,fpos_t *); 477 extern int Usetpos(FILES *,fpos_t *); 478 extern void Usetbuf(FILES *,char *); 479 #define Usync(f) fsync(f->descriptor) 480 #define Utruncate(f) { \ 481 if ( ftruncate(f->descriptor, 0) ) { \ 482 MLOCK(ErrorMessageLock); \ 483 MesPrint("Utruncate failed"); \ 484 MUNLOCK(ErrorMessageLock); \ 485 /* Calling Terminate() here may cause an infinite loop due to CleanUpSort(). */ \ 486 /* Terminate(-1); */ \ 487 } \ 488 } 489 extern FILES *Ustdout; 490 #define MAX_OPEN_FILES getdtablesize() 491 #define GetPID() ((LONG)getpid()) 492 493 #else /* UNIX */ 494 495 #define FILES FILE 496 #define Uopen(x,y) fopen(x,y) 497 #define Uflush(x) fflush(x) 498 #define Uclose(x) fclose(x) 499 #define Uread(x,y,z,u) fread(x,y,z,u) 500 #define Uwrite(x,y,z,u) fwrite(x,y,z,u) 501 #define Usetbuf(x,y) setbuf(x,y) 502 #define Useek(x,y,z) fseek(x,y,z) 503 #define Utell(x) ftell(x) 504 #define Ugetpos(x,y) fgetpos(x,y) 505 #define Usetpos(x,y) fsetpos(x,y) 506 #define Usync(x) fflush(x) 507 #define Utruncate(x) _chsize(_fileno(x),0) 508 #define Ustdout stdout 509 #define MAX_OPEN_FILES FOPEN_MAX 510 #define bzero(b,len) (memset((b), 0, (len)), (void)0) 511 #define GetPID() ((LONG)GetCurrentProcessId()) 512 513 #endif /* UNIX */ 514 515 #ifdef WITHMPI 516 #include "parallel.h" 517 #endif 518 519 #endif /* __FORM3H__ */ 520