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-2023 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)
67extern 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)
76long 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)
90double 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 */
103extern 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)
142typedef unsigned char u_char;
143typedef unsigned int u_int;
144typedef unsigned long u_long;
145typedef 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>
167typedef 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 analyers, 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. */
465typedef _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 erronous 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