BRL-CAD
common.h
Go to the documentation of this file.
1 /* C O M M O N . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 /** @addtogroup common
22  *
23  * This header wraps system and compilation-specific defines from
24  * brlcad_config.h and removes need to conditionally include
25  * brlcad_config.h everywhere based on HAVE_CONFIG_H. The common
26  * definitions are symbols common to the platform being built that are
27  * either detected via configure or hand crafted, as is the case for
28  * the win32 platform.
29  *
30  * NOTE: In order to use compile-time API, applications need to define
31  * BRLCADBUILD and HAVE_CONFIG_H before including this header.
32  *
33  */
34 /** @{ */
35 /** @brief Header file for the BRL-CAD common definitions. */
36 /** @file common.h */
37 
38 #ifndef COMMON_H
39 #define COMMON_H
40 
41 /* include the venerable config.h file. use a pregenerated one for
42  * windows when we cannot auto-generate it easily. do not include
43  * config.h if this file has been installed. (public header files
44  * should not use config defines)
45  */
46 #if defined(BRLCADBUILD) && defined(HAVE_CONFIG_H)
47 
48 # if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
49 # include "brlcad_config.h"
50  /* Put Windows config after brlcad_config.h, since some of the
51  * tests in it require defines from brlcad_config.h
52  */
53 # include "config_win.h"
54 # else
55 # include "brlcad_config.h"
56 # endif /* _WIN32 */
57 
58 /* Simulates drand48() functionality using rand() which is assumed to
59  * exist everywhere. The range is [0, 1).
60  */
61 # if !defined(HAVE_DRAND48) && !defined(drand48)
62 # define drand48() ((double)rand() / (double)(RAND_MAX + 1))
63 # define HAVE_DRAND48 1
64 # define srand48(seed) (srand(seed))
65 # define HAVE_DECL_DRAND48 1
66 # elif !defined(HAVE_DECL_DRAND48) && !defined(__cplusplus)
67 extern double drand48(void);
68 # endif
69 
70 # if !defined(__cplusplus) || defined(HAVE_SHARED_RINT_TEST)
71 /* make sure lrint() is provided */
72 # if !defined(lrint)
73 # if !defined(HAVE_LRINT)
74 # define lrint(_x) (((_x) < 0.0) ? (long int)ceil((_x)-0.5) : (long int)floor((_x)+0.5))
75 # elif !defined(HAVE_WINDOWS_H) && !defined(HAVE_DECL_LRINT)
76 long int lrint(double x);
77 # define HAVE_DECL_LRINT 1
78 # endif
79 # endif
80 
81 # if !defined(HAVE_LRINT)
82 # define HAVE_LRINT 1
83 # endif
84 
85 /* make sure rint() is provided */
86 # if !defined(rint)
87 # if !defined(HAVE_RINT)
88 # define rint(_x) (((_x) < 0.0) ? ceil((_x)-0.5) : floor((_x)+0.5))
89 # elif !defined(HAVE_WINDOWS_H) && !defined(HAVE_DECL_RINT)
90 double rint(double x);
91 # define HAVE_DECL_RINT 1
92 # endif
93 # endif
94 
95 # if !defined(HAVE_RINT)
96 # define HAVE_RINT 1
97 # endif
98 # endif
99 
100 /* strict c89 doesn't declare snprintf() */
101 # if defined(HAVE_SNPRINTF) && !defined(HAVE_DECL_SNPRINTF) && !defined(snprintf) && !defined(__cplusplus)
102 # include <stddef.h> /* for size_t */
103 extern int snprintf(char *str, size_t size, const char *format, ...);
104 # endif
105 
106 #endif /* BRLCADBUILD & HAVE_CONFIG_H */
107 
108 /* provide declaration markers for header externals */
109 #ifndef __BEGIN_DECLS
110 # ifdef __cplusplus
111 # define __BEGIN_DECLS extern "C" { /**< if C++, set to extern "C" { */
112 # define __END_DECLS } /**< if C++, set to } */
113 # else
114 # define __BEGIN_DECLS /**< if C++, set to extern "C" { */
115 # define __END_DECLS /**< if C++, set to } */
116 # endif
117 #endif
118 
119 /* ANSI c89 does not allow the 'inline' keyword, check if GNU inline
120  * rules are in effect.
121  *
122  * TODO: test removal of __STRICT_ANSI__ on Windows.
123  */
124 #if !defined __cplusplus && (defined(__STRICT_ANSI__) || defined(__GNUC_GNU_INLINE__))
125 # ifndef inline
126 # define inline /***/
127 # endif
128 #endif
129 
130 /** Find and return the maximum value */
131 #ifndef FMAX
132 # define FMAX(a, b) (((a)>(b))?(a):(b))
133 #endif
134 /** Find and return the minimum value */
135 #ifndef FMIN
136 # define FMIN(a, b) (((a)<(b))?(a):(b))
137 #endif
138 
139 /* make sure the old bsd types are defined for portability */
140 #if defined(BRLCADBUILD) && defined(HAVE_CONFIG_H)
141 # if !defined(HAVE_U_TYPES)
142 typedef unsigned char u_char;
143 typedef unsigned int u_int;
144 typedef unsigned long u_long;
145 typedef unsigned short u_short;
146 # define HAVE_U_TYPES 1
147 # endif
148 #endif
149 
150 /* We want 64 bit (large file) I/O capabilities whenever they are available.
151  * Always define this before we include sys/types.h */
152 #ifndef _FILE_OFFSET_BITS
153 # define _FILE_OFFSET_BITS 64
154 #endif
155 
156 /**
157  * make sure ssize_t is provided. C99 does not provide it even though it is
158  * defined in SUS97. if not available, we create the type aligned with the
159  * similar POSIX ptrdiff_t type.
160  */
161 #if defined(_MSC_VER) && !defined(HAVE_SSIZE_T)
162 # ifdef HAVE_SYS_TYPES_H
163 # include <sys/types.h>
164 # endif
165 # include <limits.h>
166 # include <stddef.h>
167 typedef ptrdiff_t ssize_t;
168 # define HAVE_SSIZE_T 1
169 # ifndef SSIZE_MAX
170 # if defined(LONG_MAX)
171 # define SSIZE_MAX LONG_MAX
172 # elif defined(INT_MAX)
173 # define SSIZE_MAX INT_MAX
174 # elif defined(_POSIX_SSIZE_MAX)
175 # define SSIZE_MAX _POSIX_SSIZE_MAX
176 # else
177  /* Go with POSIX minimum acceptable value. This is smaller than
178  * we would like, but is a safe default value.
179  */
180 # define SSIZE_MAX 32767
181 # endif
182 # endif
183 #endif
184 
185 /* make sure most of the C99 stdint types are provided including the
186  * optional uintptr_t type.
187  */
188 #if !defined(INT8_MAX) || !defined(INT16_MAX) || !defined(INT32_MAX) || !defined(INT64_MAX)
189 # if (defined _MSC_VER && (_MSC_VER <= 1500))
190  /* Older Versions of Visual C++ seem to need pstdint.h but still
191  * pass the tests below, so force it based on version (ugh.)
192  */
193 # include "pstdint.h"
194 # elif defined(__STDC__) || defined(__STRICT_ANSI__) || defined(__SIZE_TYPE__) || defined(HAVE_STDINT_H)
195 # if !defined(__STDC_LIMIT_MACROS)
196 # define __STDC_LIMIT_MACROS 1
197 # endif
198 # if !defined(__STDC_CONSTANT_MACROS)
199 # define __STDC_CONSTANT_MACROS 1
200 # endif
201 # include <stdint.h>
202 # else
203 # include "pstdint.h"
204 # endif
205 #endif
206 
207 /* off_t is 32 bit size even on 64 bit Windows. In the past we have tried to
208  * force off_t to be 64 bit but this is failing on newer Windows/Visual Studio
209  * versions in 2020 - therefore, we instead introduce the b_off_t define to
210  * properly substitute the correct numerical type for the correct platform. */
211 #if defined(_WIN64)
212 # include <sys/stat.h>
213 # define b_off_t __int64
214 # define fstat _fstati64
215 # define stat _stati64
216 #elif defined (_WIN32)
217 # include <sys/stat.h>
218 # define b_off_t _off_t
219 # define fstat _fstat
220 # define stat _stat
221 #else
222 # define b_off_t off_t
223 #endif
224 
225 /**
226  * Maximum length of a filesystem path. Typically defined in a system
227  * file but if it isn't set, we create it.
228  */
229 #ifndef MAXPATHLEN
230 # include <limits.h> // Consistently define (or not) PATH_MAX
231 # ifdef PATH_MAX
232 # define MAXPATHLEN PATH_MAX
233 # elif defined(MAX_PATH)
234 # define MAXPATHLEN MAX_PATH
235 # elif defined(_MAX_PATH)
236 # define MAXPATHLEN _MAX_PATH
237 # else
238 # define MAXPATHLEN 2048
239 # endif
240 #endif
241 
242 /**
243  * Provide a means to conveniently test the version of the GNU
244  * compiler. Use it like this:
245  *
246  * @code
247  * #if GCC_PREREQ(2,8)
248  * ... code requiring gcc 2.8 or later ...
249  * #endif
250  * @endcode
251  *
252  * WARNING: THIS MACRO IS CONSIDERED PRIVATE AND SHOULD NOT BE USED
253  * OUTSIDE OF THIS HEADER FILE. DO NOT RELY ON IT.
254  */
255 #ifdef GCC_PREREQ
256 # warning "GCC_PREREQ unexpectedly defined. Ensure common.h is included first."
257 # undef GCC_PREREQ
258 #endif
259 #if defined __GNUC__
260 # define GCC_PREREQ(major, minor) __GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))
261 #else
262 # define GCC_PREREQ(major, minor) 0
263 #endif
264 
265 /**
266  * Provide a means to conveniently test the version of the Intel
267  * compiler. Use it like this:
268  *
269  * @code
270  * #if ICC_PREREQ(800)
271  * ... code requiring icc 8.0 or later ...
272  * #endif
273  * @endcode
274  *
275  * WARNING: THIS MACRO IS CONSIDERED PRIVATE AND SHOULD NOT BE USED
276  * OUTSIDE OF THIS HEADER FILE. DO NOT RELY ON IT.
277  */
278 /* provide a means to conveniently test the version of ICC */
279 #ifdef ICC_PREREQ
280 # warning "ICC_PREREQ unexpectedly defined. Ensure common.h is included first."
281 # undef ICC_PREREQ
282 #endif
283 #if defined __INTEL_COMPILER
284 # define ICC_PREREQ(version) (__INTEL_COMPILER >= (version))
285 #else
286 # define ICC_PREREQ(version) 0
287 #endif
288 
289 /* This is so we can use gcc's "format string vs arguments"-check for
290  * various printf-like functions, and still maintain compatibility.
291  */
292 #ifndef __attribute__
293 /* This feature is only available in gcc versions 2.5 and later. */
294 # if !GCC_PREREQ(2, 5)
295 # define __attribute__(ignore) /* empty */
296 # endif
297 /* The __-protected variants of `format' and `printf' attributes
298  * are accepted by gcc versions 2.6.4 (effectively 2.7) and later.
299  */
300 # if !GCC_PREREQ(2, 7)
301 # define __format__ format
302 # define __printf__ printf
303 # define __noreturn__ noreturn
304 # endif
305 #endif
306 
307 /* gcc 3.4 doesn't seem to support always_inline with -O0 (yet -Os
308  * reportedly works), so turn it off.
309  */
310 #if !GCC_PREREQ(3, 5)
311 # define always_inline noinline
312 #endif
313 
314 /**
315  * UNUSED provides a common mechanism for declaring unused parameters.
316  * Use it like this:
317  *
318  * int
319  * my_function(int argc, char **UNUSED(argv))
320  * {
321  * ...
322  * }
323  *
324  */
325 #ifdef UNUSED
326 # warning "UNUSED unexpectedly defined. Ensure common.h is included first."
327 # undef UNUSED
328 #endif
329 #if GCC_PREREQ(2, 5)
330 /* GCC-style compilers have an attribute */
331 # define UNUSED(parameter) UNUSED_ ## parameter __attribute__((unused))
332 #elif defined(__cplusplus)
333 /* C++ allows the name to go away */
334 # define UNUSED(parameter) /* parameter */
335 #else
336 /* some are asserted when !NDEBUG */
337 # define UNUSED(parameter) (parameter)
338 #endif
339 
340 /**
341  * LIKELY provides a common mechanism for providing branch prediction
342  * hints to the compiler so that it can better optimize. It should be
343  * used when it's exceptionally likely that an expected code path will
344  * almost always be executed. Use it like this:
345  *
346  * if (LIKELY(x == 1)) {
347  * ... expected code path ...
348  * }
349  *
350  */
351 #ifdef LIKELY
352 # undef LIKELY
353 # warning "LIKELY unexpectedly defined. Ensure common.h is included first."
354 #endif
355 #if GCC_PREREQ(3, 0) || ICC_PREREQ(800)
356 # define LIKELY(expression) __builtin_expect((expression), 1)
357 #else
358 # define LIKELY(expression) (expression)
359 #endif
360 
361 /**
362  * UNLIKELY provides a common mechanism for providing branch
363  * prediction hints to the compiler so that it can better optimize.
364  * It should be used when it's exceptionally unlikely that a given code
365  * path will ever be executed. Use it like this:
366  *
367  * if (UNLIKELY(x == 0)) {
368  * ... unexpected code path ...
369  * }
370  *
371  */
372 #ifdef UNLIKELY
373 # undef UNLIKELY
374 # warning "UNLIKELY unexpectedly defined. Ensure common.h is included first."
375 #endif
376 #if GCC_PREREQ(3, 0) || ICC_PREREQ(800)
377 # define UNLIKELY(expression) __builtin_expect((expression), 0)
378 #else
379 # define UNLIKELY(expression) (expression)
380 #endif
381 
382 /**
383  * DEPRECATED provides a common mechanism for denoting public API
384  * (e.g., functions, typedefs, variables) that is considered
385  * deprecated. Use it like this:
386  *
387  * DEPRECATED int my_function(void);
388  *
389  * typedef struct karma some_type DEPRECATED;
390  */
391 #ifdef DEPRECATED
392 # undef DEPRECATED
393 # warning "DEPRECATED unexpectedly defined. Ensure common.h is included first."
394 #endif
395 #if GCC_PREREQ(3, 1) || ICC_PREREQ(800)
396 # define DEPRECATED __attribute__((deprecated))
397 #elif defined(_WIN32)
398 # define DEPRECATED __declspec(deprecated("This function is DEPRECATED. Please update code to new API."))
399 #else
400 # define DEPRECATED /* deprecated */
401 #endif
402 
403 
404 /**
405  * NORETURN declares that a function does not return.
406  *
407  * For portability, the attribute must precede the function, i.e., be
408  * declared on the left:
409  *
410  * NORETURN void function(void);
411  *
412  * Note that throwing an exception or calling longjmp() do not
413  * constitute a return. Functions that (always) infinite loop can be
414  * considered functions that do not return. Functions that do not
415  * return should have a void return type. This option is a hint to
416  * compilers and static analyzers, to reduce false positive reporting.
417  */
418 #ifdef NORETURN
419 # undef NORETURN
420 # warning "NORETURN unexpectedly defined. Ensure common.h is included first."
421 #endif
422 #if defined(HAVE_NORETURN_ATTRIBUTE)
423 # define NORETURN __attribute__((__noreturn__))
424 #elif defined(HAVE_NORETURN_DECLSPEC)
425 # define NORETURN __declspec(noreturn)
426 #else
427 # define NORETURN /* does not return */
428 #endif
429 
430 
431 /**
432  * FAUX_NORETURN declares a function should be treated as if it does
433  * not return, even though it can.
434  *
435  * As this label is (currently) Clang-specific, it can be declared on
436  * the left or right of a function declaration. Left is recommended
437  * for consistency with other annotations, e.g.:
438  *
439  * FAUX_NORETURN void function(void);
440  *
441  * This annocation is almost identical to NORETURN except that it does
442  * not affect code generation and can be used on functions that
443  * actually return. It's typically useful for annotating assertion
444  * handlers (e.g., assert()) that sometimes return and should not be
445  * used on NORETURN functions. This annotation is primarily a hint to
446  * static analyzers.
447  */
448 #ifdef FAUX_NORETURN
449 # undef FAUX_NORETURN
450 # warning "FAUX_NORETURN unexpectedly defined. Ensure common.h is included first."
451 #endif
452 #ifdef HAVE_ANALYZER_NORETURN_ATTRIBUTE
453 # define FAUX_NORETURN __attribute__((analyzer_noreturn))
454 #else
455 # define FAUX_NORETURN /* pretend does not return */
456 #endif
457 
458 
459 /* ActiveState Tcl doesn't include this catch in tclPlatDecls.h, so we
460  * have to add it for them
461  */
462 #if defined(_MSC_VER) && defined(__STDC__)
463 # include <tchar.h>
464 /* MSVC++ misses this. */
465 typedef _TCHAR TCHAR;
466 #endif
467 
468 /* Avoid -Wundef warnings for system headers that use __STDC_VERSION__ without
469  * checking if it's defined.
470  */
471 #if !defined(__STDC_VERSION__)
472 # define __STDC_VERSION__ 0
473 #endif
474 
475 /**
476  * globally disable certain warnings. do NOT add new warnings here
477  * without discussion and research. only warnings that cannot be
478  * quieted without objectively decreasing code quality should be
479  * added! even warnings that are innocuous or produce false-positive
480  * should be quelled when possible.
481  *
482  * any warnings added should include a description and justification.
483  */
484 #if defined(_MSC_VER)
485 
486 /* /W1 warning C4351: new behavior: elements of array '...' will be default initialized
487  *
488  * i.e., this is the "we now implement constructor member
489  * initialization correctly" warning that tells the user an
490  * initializer like this:
491  *
492  * Class::Class() : some_array() {}
493  *
494  * will now initialize all members of some_array. previous to
495  * MSVC2005, behavior was to not initialize in some cases...
496  */
497 # pragma warning( disable : 4351 )
498 
499 /* warning C5105: macro expansion producing 'defined' has undefined behavior
500  *
501  * this appears to be an erroneous issue in the latest msvc
502  * pre-processor that has support for the new C17 standard, which
503  * triggers warnings in Windows SDK headers (e.g., winbase.h) that
504  * use the defined operator in certain macros.
505  */
506 # pragma warning( disable : 5105 )
507 
508 /* dubious warnings that are not yet intentionally disabled:
509  *
510  * /W3 warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
511  *
512  * this warning is caused by assigning an int (or other non-boolean
513  * value) to a bool like this:
514  *
515  * int i = 1; bool b = i;
516  *
517  * there is something to be said for making such assignments explicit,
518  * e.g., "b = (i != 0);", but this arguably decreases readability or
519  * clarity and the fix has potential for introducing logic errors.
520  */
521 /*# pragma warning( disable : 4800 ) */
522 
523 #endif
524 
525 /**
526  * Provide a macro for different treatment of initialized extern const
527  * variables between C and C++. In C the following initialization
528  * (definition) is acceptable for external linkage:
529  *
530  * const int var = 10;
531  *
532  * but in C++ const is implicitly internal linkage so it must have
533  * extern qualifier:
534  *
535  * extern const int var = 10;
536  */
537 #if defined(__cplusplus)
538 # define EXTERNVARINIT extern
539 #else
540 # define EXTERNVARINIT
541 #endif
542 
543 /**
544  * Provide canonical preprocessor stringification.
545  *
546  @code
547  * #define abc 123
548  * CPP_STR(abc) => "abc"
549  @endcode
550  */
551 #ifndef CPP_STR
552 # define CPP_STR(x) # x
553 #endif
554 
555 /**
556  * Provide canonical preprocessor expanded stringification.
557  *
558  @code
559  * #define abc 123
560  * CPP_XSTR(abc) => "123"
561  @endcode
562  */
563 #ifndef CPP_XSTR
564 # define CPP_XSTR(x) CPP_STR(x)
565 #endif
566 
567 /**
568  * Provide canonical preprocessor concatenation.
569  *
570  @code
571  * #define abc 123
572  * CPP_GLUE(abc, 123) => abc123
573  * CPP_STR(CPP_GLUE(abc, 123)) => "CPP_GLUE(abc, 123)"
574  * CPP_XSTR(CPP_GLUE(abc, 123)) => "abc123"
575  * #define abc123 "xyz"
576  * CPP_GLUE(abc, 123) => abc123 => "xyz"
577  @endcode
578  */
579 #ifndef CPP_GLUE
580 # define CPP_GLUE(a, b) a ## b
581 #endif
582 
583 /**
584  * Provide canonical preprocessor expanded concatenation.
585  *
586  @code
587  * #define abc 123
588  * CPP_XGLUE(abc, 123) => 123123
589  * CPP_STR(CPP_XGLUE(abc, 123)) => "CPP_XGLUE(abc, 123)"
590  * CPP_XSTR(CPP_XGLUE(abc, 123)) => "123123"
591  @endcode
592  */
593 #ifndef CPP_XGLUE
594 # define CPP_XGLUE(a, b) CPP_GLUE(a, b)
595 #endif
596 
597 /**
598  * Provide format specifier string tied to a size (e.g., "%123s")
599  *
600  @code
601  * #define STR_LEN 10+1
602  * char str[STR_LEN] = {0};
603  * scanf(CPP_SCANSIZE(STR_LEN) "\n", str);
604  @endcode
605  */
606 #ifndef CPP_SCAN
607 # define CPP_SCAN(sz) "%" CPP_XSTR(sz) "s"
608 #endif
609 
610 /**
611  * Provide the current filename and linenumber as a static
612  * preprocessor string in "file"":""line" format (e.g., "file:123").
613  */
614 #ifndef CPP_FILELINE
615 # define CPP_FILELINE __FILE__ ":" CPP_XSTR(__LINE__)
616 #endif
617 
618 /**
619  * If we've not already defined COMPILER_DLLEXPORT and COMPILER_DLLIMPORT,
620  * define them away so code including the *_EXPORT header logic won't
621  * fail.
622  */
623 #if defined(_MSC_VER)
624 # define COMPILER_DLLEXPORT __declspec(dllexport)
625 # define COMPILER_DLLIMPORT __declspec(dllimport)
626 #elif defined(__GNUC__) || defined(__clang__)
627 # define COMPILER_DLLEXPORT __attribute__ ((visibility ("default")))
628 # define COMPILER_DLLIMPORT __attribute__ ((visibility ("default")))
629 #else
630 # define COMPILER_DLLEXPORT
631 # define COMPILER_DLLIMPORT
632 #endif
633 
634 #endif /* COMMON_H */
635 
636 /** @} */
637 /*
638  * Local Variables:
639  * mode: C
640  * tab-width: 8
641  * indent-tabs-mode: t
642  * c-file-style: "stroustrup"
643  * End:
644  * ex: shiftwidth=4 tabstop=8
645  */
void float float int int int int float * size
Definition: tig.h:132
void float * x
Definition: tig.h:72