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-2022 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/**
120 * Functions local to one file IN A LIBRARY should be declared HIDDEN.
121 * Disabling the static classifier is sometimes helpful for debugging.
122 * It can help prevent some compilers from inlining functions that one
123 * might want to set a breakpoint on. Do not use on variables.
124 */
125#if !defined(HIDDEN)
126# if defined(NDEBUG)
127# define HIDDEN static
128# else
129# define HIDDEN /***/
130# endif
131#endif
132
133/* ANSI c89 does not allow the 'inline' keyword, check if GNU inline
134 * rules are in effect.
135 *
136 * TODO: test removal of __STRICT_ANSI__ on Windows.
137 */
138#if !defined __cplusplus && (defined(__STRICT_ANSI__) || defined(__GNUC_GNU_INLINE__))
139# ifndef inline
140# define inline /***/
141# endif
142#endif
143
144/** Find and return the maximum value */
145#ifndef FMAX
146# define FMAX(a, b) (((a)>(b))?(a):(b))
147#endif
148/** Find and return the minimum value */
149#ifndef FMIN
150# define FMIN(a, b) (((a)<(b))?(a):(b))
151#endif
152
153/* make sure the old bsd types are defined for portability */
154#if defined(BRLCADBUILD) && defined(HAVE_CONFIG_H)
155# if !defined(HAVE_U_TYPES)
156typedef unsigned char u_char;
157typedef unsigned int u_int;
158typedef unsigned long u_long;
159typedef unsigned short u_short;
160# define HAVE_U_TYPES 1
161# endif
162#endif
163
164/* We want 64 bit (large file) I/O capabilities whenever they are available.
165 * Always define this before we include sys/types.h */
166#ifndef _FILE_OFFSET_BITS
167# define _FILE_OFFSET_BITS 64
168#endif
169
170/**
171 * C99 does not provide a ssize_t even though it is provided by SUS97.
172 * regardless, we use it so make sure it's declared by using the
173 * similar POSIX ptrdiff_t type.
174 */
175#if defined(BRLCADBUILD) && defined(HAVE_CONFIG_H)
176# ifndef HAVE_SSIZE_T
177# ifdef HAVE_SYS_TYPES_H
178# include <sys/types.h>
179# endif
180# include <limits.h>
181# include <stddef.h>
182# ifndef SSIZE_MAX
183typedef ptrdiff_t ssize_t;
184# define HAVE_SSIZE_T 1
185# if defined(_WIN64)
186# define SSIZE_MAX LONG_MAX
187# else
188# define SSIZE_MAX INT_MAX
189# endif
190# endif
191# endif
192#endif
193
194/* make sure most of the C99 stdint types are provided including the
195 * optional uintptr_t type.
196 */
197#if !defined(INT8_MAX) || !defined(INT16_MAX) || !defined(INT32_MAX) || !defined(INT64_MAX)
198# if (defined _MSC_VER && (_MSC_VER <= 1500))
199 /* Older Versions of Visual C++ seem to need pstdint.h but still
200 * pass the tests below, so force it based on version (ugh.)
201 */
202# include "pstdint.h"
203# elif defined(__STDC__) || defined(__STRICT_ANSI__) || defined(__SIZE_TYPE__) || defined(HAVE_STDINT_H)
204# if !defined(__STDC_LIMIT_MACROS)
205# define __STDC_LIMIT_MACROS 1
206# endif
207# if !defined(__STDC_CONSTANT_MACROS)
208# define __STDC_CONSTANT_MACROS 1
209# endif
210# include <stdint.h>
211# else
212# include "pstdint.h"
213# endif
214#endif
215
216/* off_t is 32 bit size even on 64 bit Windows. In the past we have tried to
217 * force off_t to be 64 bit but this is failing on newer Windows/Visual Studio
218 * versions in 2020 - therefore, we instead introduce the b_off_t define to
219 * properly substitute the correct numerical type for the correct platform. */
220#if defined(_WIN64)
221# include <sys/stat.h>
222# define b_off_t __int64
223# define fstat _fstati64
224# define stat _stati64
225#elif defined (_WIN32)
226# include <sys/stat.h>
227# define b_off_t _off_t
228# define fstat _fstat
229# define stat _stat
230#else
231# define b_off_t off_t
232#endif
233
234/**
235 * Maximum length of a filesystem path. Typically defined in a system
236 * file but if it isn't set, we create it.
237 */
238#ifndef MAXPATHLEN
239# include <limits.h> // Consistently define (or not) PATH_MAX
240# ifdef PATH_MAX
241# define MAXPATHLEN PATH_MAX
242# elif defined(MAX_PATH)
243# define MAXPATHLEN MAX_PATH
244# elif defined(_MAX_PATH)
245# define MAXPATHLEN _MAX_PATH
246# else
247# define MAXPATHLEN 2048
248# endif
249#endif
250
251/**
252 * Provide a means to conveniently test the version of the GNU
253 * compiler. Use it like this:
254 *
255 * @code
256 * #if GCC_PREREQ(2,8)
257 * ... code requiring gcc 2.8 or later ...
258 * #endif
259 * @endcode
260 *
261 * WARNING: THIS MACRO IS CONSIDERED PRIVATE AND SHOULD NOT BE USED
262 * OUTSIDE OF THIS HEADER FILE. DO NOT RELY ON IT.
263 */
264#ifdef GCC_PREREQ
265# warning "GCC_PREREQ unexpectedly defined. Ensure common.h is included first."
266# undef GCC_PREREQ
267#endif
268#if defined __GNUC__
269# define GCC_PREREQ(major, minor) __GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))
270#else
271# define GCC_PREREQ(major, minor) 0
272#endif
273
274/**
275 * Provide a means to conveniently test the version of the Intel
276 * compiler. Use it like this:
277 *
278 * @code
279 * #if ICC_PREREQ(800)
280 * ... code requiring icc 8.0 or later ...
281 * #endif
282 * @endcode
283 *
284 * WARNING: THIS MACRO IS CONSIDERED PRIVATE AND SHOULD NOT BE USED
285 * OUTSIDE OF THIS HEADER FILE. DO NOT RELY ON IT.
286 */
287/* provide a means to conveniently test the version of ICC */
288#ifdef ICC_PREREQ
289# warning "ICC_PREREQ unexpectedly defined. Ensure common.h is included first."
290# undef ICC_PREREQ
291#endif
292#if defined __INTEL_COMPILER
293# define ICC_PREREQ(version) (__INTEL_COMPILER >= (version))
294#else
295# define ICC_PREREQ(version) 0
296#endif
297
298/* This is so we can use gcc's "format string vs arguments"-check for
299 * various printf-like functions, and still maintain compatibility.
300 */
301#ifndef __attribute__
302/* This feature is only available in gcc versions 2.5 and later. */
303# if !GCC_PREREQ(2, 5)
304# define __attribute__(ignore) /* empty */
305# endif
306/* The __-protected variants of `format' and `printf' attributes
307 * are accepted by gcc versions 2.6.4 (effectively 2.7) and later.
308 */
309# if !GCC_PREREQ(2, 7)
310# define __format__ format
311# define __printf__ printf
312# define __noreturn__ noreturn
313# endif
314#endif
315
316/* gcc 3.4 doesn't seem to support always_inline with -O0 (yet -Os
317 * reportedly works), so turn it off.
318 */
319#if !GCC_PREREQ(3, 5)
320# define always_inline noinline
321#endif
322
323/**
324 * UNUSED provides a common mechanism for declaring unused parameters.
325 * Use it like this:
326 *
327 * int
328 * my_function(int argc, char **UNUSED(argv))
329 * {
330 * ...
331 * }
332 *
333 */
334#ifdef UNUSED
335# warning "UNUSED unexpectedly defined. Ensure common.h is included first."
336# undef UNUSED
337#endif
338#if GCC_PREREQ(2, 5)
339/* GCC-style compilers have an attribute */
340# define UNUSED(parameter) UNUSED_ ## parameter __attribute__((unused))
341#elif defined(__cplusplus)
342/* C++ allows the name to go away */
343# define UNUSED(parameter) /* parameter */
344#else
345/* some are asserted when !NDEBUG */
346# define UNUSED(parameter) (parameter)
347#endif
348
349/**
350 * LIKELY provides a common mechanism for providing branch prediction
351 * hints to the compiler so that it can better optimize. It should be
352 * used when it's exceptionally likely that an expected code path will
353 * almost always be executed. Use it like this:
354 *
355 * if (LIKELY(x == 1)) {
356 * ... expected code path ...
357 * }
358 *
359 */
360#ifdef LIKELY
361# undef LIKELY
362# warning "LIKELY unexpectedly defined. Ensure common.h is included first."
363#endif
364#if GCC_PREREQ(3, 0) || ICC_PREREQ(800)
365# define LIKELY(expression) __builtin_expect((expression), 1)
366#else
367# define LIKELY(expression) (expression)
368#endif
369
370/**
371 * UNLIKELY provides a common mechanism for providing branch
372 * prediction hints to the compiler so that it can better optimize.
373 * It should be used when it's exceptionally unlikely that a given code
374 * path will ever be executed. Use it like this:
375 *
376 * if (UNLIKELY(x == 0)) {
377 * ... unexpected code path ...
378 * }
379 *
380 */
381#ifdef UNLIKELY
382# undef UNLIKELY
383# warning "UNLIKELY unexpectedly defined. Ensure common.h is included first."
384#endif
385#if GCC_PREREQ(3, 0) || ICC_PREREQ(800)
386# define UNLIKELY(expression) __builtin_expect((expression), 0)
387#else
388# define UNLIKELY(expression) (expression)
389#endif
390
391/**
392 * DEPRECATED provides a common mechanism for denoting public API
393 * (e.g., functions, typedefs, variables) that is considered
394 * deprecated. Use it like this:
395 *
396 * DEPRECATED int my_function(void);
397 *
398 * typedef struct karma some_type DEPRECATED;
399 */
400#ifdef DEPRECATED
401# undef DEPRECATED
402# warning "DEPRECATED unexpectedly defined. Ensure common.h is included first."
403#endif
404#if GCC_PREREQ(3, 1) || ICC_PREREQ(800)
405# define DEPRECATED __attribute__((deprecated))
406#elif defined(_WIN32)
407# define DEPRECATED __declspec(deprecated("This function is DEPRECATED. Please update code to new API."))
408#else
409# define DEPRECATED /* deprecated */
410#endif
411
412
413/* ActiveState Tcl doesn't include this catch in tclPlatDecls.h, so we
414 * have to add it for them
415 */
416#if defined(_MSC_VER) && defined(__STDC__)
417# include <tchar.h>
418/* MSVC++ misses this. */
419typedef _TCHAR TCHAR;
420#endif
421
422/* Avoid -Wundef warnings for system headers that use __STDC_VERSION__ without
423 * checking if it's defined.
424 */
425#if !defined(__STDC_VERSION__)
426# define __STDC_VERSION__ 0
427#endif
428
429/**
430 * globally disable certain warnings. do NOT add new warnings here
431 * without discussion and research. only warnings that cannot be
432 * quieted without objectively decreasing code quality should be
433 * added! even warnings that are innocuous or produce false-positive
434 * should be quelled when possible.
435 *
436 * any warnings added should include a description and justification.
437 */
438#if defined(_MSC_VER)
439
440/* /W1 warning C4351: new behavior: elements of array '...' will be default initialized
441 *
442 * i.e., this is the "we now implement constructor member
443 * initialization correctly" warning that tells the user an
444 * initializer like this:
445 *
446 * Class::Class() : some_array() {}
447 *
448 * will now initialize all members of some_array. previous to
449 * MSVC2005, behavior was to not initialize in some cases...
450 */
451# pragma warning( disable : 4351 )
452
453/* dubious warnings that are not yet intentionally disabled:
454 *
455 * /W3 warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
456 *
457 * this warning is caused by assigning an int (or other non-boolean
458 * value) to a bool like this:
459 *
460 * int i = 1; bool b = i;
461 *
462 * there is something to be said for making such assignments explicit,
463 * e.g., "b = (i != 0);", but this arguably decreases readability or
464 * clarity and the fix has potential for introducing logic errors.
465 */
466/*# pragma warning( disable : 4800 ) */
467
468#endif
469
470/**
471 * Provide a macro for different treatment of initialized extern const
472 * variables between C and C++. In C the following initialization
473 * (definition) is acceptable for external linkage:
474 *
475 * const int var = 10;
476 *
477 * but in C++ const is implicitly internal linkage so it must have
478 * extern qualifier:
479 *
480 * extern const int var = 10;
481 */
482#if defined(__cplusplus)
483# define EXTERNVARINIT extern
484#else
485# define EXTERNVARINIT
486#endif
487
488/**
489 * Provide canonical preprocessor stringification.
490 *
491 @code
492 * #define abc 123
493 * CPP_STR(abc) => "abc"
494 @endcode
495 */
496#ifndef CPP_STR
497# define CPP_STR(x) # x
498#endif
499
500/**
501 * Provide canonical preprocessor expanded stringification.
502 *
503 @code
504 * #define abc 123
505 * CPP_XSTR(abc) => "123"
506 @endcode
507 */
508#ifndef CPP_XSTR
509# define CPP_XSTR(x) CPP_STR(x)
510#endif
511
512/**
513 * Provide canonical preprocessor concatenation.
514 *
515 @code
516 * #define abc 123
517 * CPP_GLUE(abc, 123) => abc123
518 * CPP_STR(CPP_GLUE(abc, 123)) => "CPP_GLUE(abc, 123)"
519 * CPP_XSTR(CPP_GLUE(abc, 123)) => "abc123"
520 * #define abc123 "xyz"
521 * CPP_GLUE(abc, 123) => abc123 => "xyz"
522 @endcode
523 */
524#ifndef CPP_GLUE
525# define CPP_GLUE(a, b) a ## b
526#endif
527
528/**
529 * Provide canonical preprocessor expanded concatenation.
530 *
531 @code
532 * #define abc 123
533 * CPP_XGLUE(abc, 123) => 123123
534 * CPP_STR(CPP_XGLUE(abc, 123)) => "CPP_XGLUE(abc, 123)"
535 * CPP_XSTR(CPP_XGLUE(abc, 123)) => "123123"
536 @endcode
537 */
538#ifndef CPP_XGLUE
539# define CPP_XGLUE(a, b) CPP_GLUE(a, b)
540#endif
541
542/**
543 * Provide format specifier string tied to a size (e.g., "%123s")
544 *
545 @code
546 * #define STR_LEN 10+1
547 * char str[STR_LEN] = {0};
548 * scanf(CPP_SCANSIZE(STR_LEN) "\n", str);
549 @endcode
550 */
551#ifndef CPP_SCAN
552# define CPP_SCAN(sz) "%" CPP_XSTR(sz) "s"
553#endif
554
555/**
556 * Provide the current filename and linenumber as a static
557 * preprocessor string in "file"":""line" format (e.g., "file:123").
558 */
559#ifndef CPP_FILELINE
560# define CPP_FILELINE __FILE__ ":" CPP_XSTR(__LINE__)
561#endif
562
563/**
564 * If we've not already defined COMPILER_DLLEXPORT and COMPILER_DLLIMPORT,
565 * define them away so code including the *_EXPORT header logic won't
566 * fail.
567 */
568#if defined(_MSC_VER)
569# define COMPILER_DLLEXPORT __declspec(dllexport)
570# define COMPILER_DLLIMPORT __declspec(dllimport)
571#elif defined(__GNUC__) || defined(__clang__)
572# define COMPILER_DLLEXPORT __attribute__ ((visibility ("default")))
573# define COMPILER_DLLIMPORT __attribute__ ((visibility ("default")))
574#else
575# define COMPILER_DLLEXPORT
576# define COMPILER_DLLIMPORT
577#endif
578
579#endif /* COMMON_H */
580
581/** @} */
582/*
583 * Local Variables:
584 * mode: C
585 * tab-width: 8
586 * indent-tabs-mode: t
587 * c-file-style: "stroustrup"
588 * End:
589 * ex: shiftwidth=4 tabstop=8
590 */
void float float int int int int float * size
Definition: tig.h:132
void float * x
Definition: tig.h:72