aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-10-12 22:20:33 +0200
committerMattias Andrée <maandree@operamail.com>2015-10-12 22:21:29 +0200
commit595e89bf46faca9f511a6cd0b3f10c53e1b23110 (patch)
tree65cc61a359a705a68d5202ad8f968772362ec5aa
parentsome feature-test macros (diff)
downloadslibc-595e89bf46faca9f511a6cd0b3f10c53e1b23110.tar.gz
slibc-595e89bf46faca9f511a6cd0b3f10c53e1b23110.tar.bz2
slibc-595e89bf46faca9f511a6cd0b3f10c53e1b23110.tar.xz
feature-test macros
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--doc/info/chap/introduction.texinfo54
-rw-r--r--include/slibc/attributes.h131
-rw-r--r--include/slibc/c-version.h81
-rw-r--r--include/slibc/features.h191
-rw-r--r--include/slibc/portability.h195
5 files changed, 521 insertions, 131 deletions
diff --git a/doc/info/chap/introduction.texinfo b/doc/info/chap/introduction.texinfo
index 43f4898..1501dc0 100644
--- a/doc/info/chap/introduction.texinfo
+++ b/doc/info/chap/introduction.texinfo
@@ -336,5 +336,59 @@ Enables functionality from @i{System V Interface
Description} (@sc{SVID}), as well as @sc{ISO}@tie{}C,
@sc{POSIX}.1, @sc{POSIX}.2, and X/Open.
+@item _XOPEN_SOURCE
+@cpindex X/Open Portability Guide
+@lvindex _XOPEN_SOURCE
+Enables functionality from @i{X/Open Portability Guide},
+included in @sc{BSD} and @sc{SVID}, as well as
+@sc{POSIX}.1 and @sc{POSIX}.2.
+
+@item _XOPEN_SOURCE_EXTENDED
+@cpindex X/Open Portability Guide
+@lvindex _XOPEN_SOURCE
+@lvindex _XOPEN_SOURCE_EXTENDED
+Enables all functionality that @code{_XOPEN_SOURCE}
+enables, and functionality that is required for the
+X/Open Unix brand.
+
+@item _XOPEN_SOURCE >= 500
+@cpindex X/Open Portability Guide
+@cpindex Single Unix Specification
+@cpindex @sc{SUS}
+@lvindex _XOPEN_SOURCE
+@lvindex _XOPEN_SOURCE_EXTENDED
+Enables all functionality that @code{_XOPEN_SOURCE_EXTENDED}
+enables. It also enables functionality from version 2
+of the @i{Single Unix Specification} (@sc{SUS}).
+
+@item _GNU_SOURCE
+@cpindex @sc{GNU}'s not Unix
+@cpindex @sc{GNU} C Libraries
+@lvindex _GNU_SOURCE
+Enables all functionality from @sc{ISO}@tie{}C89,
+@sc{ISO}@tie{}C99, @sc{POSIX}.1, @sc{POSIX}.2,
+@sc{BSD}, @sc{SVID}, X/Open, @sc{SUS}, the
+Large File Support extension, and extensions
+derived from the @sc{GNU} C Libraries. It also
+defines @code{_ATFILE_SOURCE}.
+
+@lvindex _BSD_SOURCE
+@sc{POSIX}.1 takes precedence when there are
+conflicts between @sc{POSIX}.1 and @sc{BSD}
+or @sc{SVID}. To override this, define
+@code{_BSD_SOURCE}.
+
+@code{_GNU_SOURCE} does not automatically
+define @code{_BSD_SOURCE} or @code{_SVID_SOURCE}.
+
@end table
+@c TODO: _LARGEFILE_SUPPORT
+@c TODO: _LARGEFILE64_SUPPORT
+@c TODO: _FILE_OFFSET_BITS
+@c TODO: _ATFILE_SOURCE
+@c TODO: _DEFAULT_SOURCE
+@c TODO: _REETRANT
+@c TODO: _THREADSAFE (alias for _REETRANT)
+@c TODO: _POSIX_C_SOURCE >= 200112L
+@c TODO: _POSIX_C_SOURCE >= 200809L
diff --git a/include/slibc/attributes.h b/include/slibc/attributes.h
new file mode 100644
index 0000000..3243ff6
--- /dev/null
+++ b/include/slibc/attributes.h
@@ -0,0 +1,131 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/* This file should be included from and only from <slibc/features.h>. */
+/* These definitions are only to be used in slibc header-files. */
+
+
+/* Clear old definitions. */
+#ifdef __noreturn
+# undef __noreturn
+#endif
+#ifdef __GCC_ONLY
+# undef __GCC_ONLY
+#endif
+#ifdef __SLIBC_ONLY
+# undef __SLIBC_ONLY
+#endif
+#ifdef __deprecated
+# undef __deprecated
+#endif
+#ifdef __warning
+# undef __warning
+#endif
+#ifdef __slibc_warning
+# undef __slibc_warning
+#endif
+#ifdef __bsd_posix_conflict
+# undef __bsd_posix_conflict
+#endif
+
+
+
+/**
+ * Specifies that a function never returns, that is,
+ * the process exits before the function returns.
+ */
+#if !defined(__C11__) && defined(__GNUC__)
+# define __noreturn __attribute__((noreturn))
+#elif defined(__C11__)
+# define __noreturn _Noreturn
+#else
+# define __noreturn /* ignore */
+#endif
+
+
+/**
+ * Macro used to exclude code unless GCC is used.
+ */
+#if defined(__GNUC__)
+# define __GCC_ONLY(...) __VA_ARGS__
+#else
+# define __GCC_ONLY(...) /* ignore */
+#endif
+
+
+/**
+ * Macro used to exclude code unless `_SLIBC_SOURCE` is set.
+ */
+#if defined(_SLIBC_SOURCE)
+# define __SLIBC_ONLY(...) __VA_ARGS__
+#else
+# define __SLIBC_ONLY(...) /* ignore */
+#endif
+
+
+/**
+ * Mark a function, variable or type as deprecated,
+ * with a message that tells the user why the the
+ * function is deprecated, or functions to use instead.
+ */
+#if !defined(_SLIBC_SUPPRESS_WARNINGS)
+# define __deprecated(msg) __GCC_ONLY(__attribute__((deprecated(msg))))
+#else
+# define __deprecated(msg) /* ignore */
+#endif
+
+
+/**
+ * Warn if a function, variable or type is used.
+ */
+#if !defined(_SLIBC_SUPPRESS_WARNINGS)
+# define __warning(msg) __GCC_ONLY(__attribute__((warning(msg))))
+# define __slibc_warning(msg) __SLIBC_ONLY(__warning(msg))
+#else
+# define __warning(msg) /* ignore */
+# define __slibc_warning(msg) /* ignore */
+#endif
+
+
+/**
+ * Functions that have a BSD-specification that is conficting
+ * with the POSIX-specification shall have this attribute.
+ */
+#if defined(_BSD_SOURCE) && !defined(_POSIX_COMPATIBLE_SOURCE) && !defined(_BSD_COMPATIBLE_SOURCE)
+# define __bsd_posix_conflict \
+ __warning("The BSD-version of this function is incompatible with the POSIX-version.")
+#else
+# define __bsd_posix_conflict /* ignore*/
+#endif
+
+
+/**
+ * Format for the `format` GCC function attribute,
+ * for `*printf` functions.
+ */
+#ifndef slibc_printf
+# define slibc_printf printf /* TODO write GCC extension */
+#endif
+
+/**
+ * Format for the `format` GCC function attribute,
+ * for `*scanf` functions.
+ */
+#ifndef slibc_scanf
+# define slibc_scanf scanf /* TODO write GCC extension */
+#endif
+
diff --git a/include/slibc/c-version.h b/include/slibc/c-version.h
new file mode 100644
index 0000000..635ddb4
--- /dev/null
+++ b/include/slibc/c-version.h
@@ -0,0 +1,81 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/* This file should be included from and only from <slibc/features.h>. */
+/* These definitions are only to be used in slibc header-files. */
+
+
+/**
+ * Is C11, or newer, used?
+ */
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || defined(__ISOC11_SOURCE)
+# if !defined(__C11__)
+# define __C11__
+# endif
+# if !defined(__ISOC11_SOURCE)
+# define __ISOC11_SOURCE
+# endif
+#endif
+
+/**
+ * Is C99, or newer, used?
+ */
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || defined(__ISOC99_SOURCE) || defined(__C11__)
+# if !defined(__C99__)
+# define __C99__
+# endif
+# if !defined(__ISOC99_SOURCE)
+# define __ISOC99_SOURCE
+# endif
+#endif
+
+/**
+ * Is C95, or newer, used?
+ */
+#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L)) || defined(__ISOC95_SOURCE) || defined(__C99__)
+# if !defined(__C95__)
+# define __C95__
+# endif
+# if !defined(__ISOC95_SOURCE)
+# define __ISOC95_SOURCE
+# endif
+#endif
+
+/**
+ * Is C90, or newer, used?
+ */
+#if defined(__STDC_VERSION__) || defined(__STDC__) || defined(__C95__) || defined(__ISOC90_SOURCE)
+# if !defined(__C90__)
+# define __C90__
+# endif
+# if !defined(__ISOC90_SOURCE)
+# define __ISOC90_SOURCE
+# endif
+#endif
+
+/**
+ * Is C89, or newer, used?
+ */
+#if defined(__C90__) || defined(__ISOC89_SOURCE)
+# if !defined(__C89__)
+# define __C89__
+# endif
+# if !defined(__ISOC89_SOURCE)
+# define __ISOC89_SOURCE
+# endif
+#endif
+
diff --git a/include/slibc/features.h b/include/slibc/features.h
index d223d76..499e4f6 100644
--- a/include/slibc/features.h
+++ b/include/slibc/features.h
@@ -22,198 +22,127 @@
/* These definitions are only to be used in slibc header-files. */
-/**
- * Macro that is defined if portability shall be ensured.
- */
-#if defined(_PORTABLE_SOURCE) || defined(_LIBRARY_HEADER)
-# define __PORTABLE
-#endif
+#include "portability.h"
+#include "c-version.h"
+#include "attributes.h"
-/**
- * Is C11, or newer, used?
- */
-#if __STDC_VERSION__ >= 201112L || defined(_ISOC11_SOURCE)
-# define __C11__
-#endif
-
-/**
- * Is C99, or newer, used?
- */
-#if __STDC_VERSION__ >= 199901L || defined(_ISOC99_SOURCE)
-# define __C99__
-#endif
/**
- * Is C90, or newer, used?
+ * _BSD_SOURCE || _SVID_SOURCE || _GNU_SOURCE implies _POSIX_C_SOURCE = 2.
*/
-#if defined(__STDC_VERSION__) || defined(__STDC__)
-# define __C90__
+#if defined(__BSD_SOURCE) || defined(__SVID_SOURCE) || defined(__GNU_SOURCE)
+# if (__POSIX_C_SOURCE <= 1L)
+# undef __POSIX_C_SOURCE
+# endif
+# if !defined(__POSIX_C_SOURCE)
+# define __POSIX_C_SOURCE 2L
+# endif
#endif
-
-
/**
- * _POSIX_SOURCE is implied if (_POSIX_C_SOURCE >= 1L).
+ * _SVID_SOURCE implies _XOPEN_SOURCE.
*/
-#if !defined(_POSIX_SOURCE) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 1L)
-# define _POSIX_SOURCE 1
-#endif
-#if (!defined(_POSIX_C_SOURCE) || (_POSIX_C_SOURCE <= 0)) && !defined(_POSIX_SOURCE)
-# define _POSIX_C_SOURCE 1L
+#if defined(__SVID_SOURCE) && !defined(__XOPEN_SOURCE)
+# define __XOPEN_SOURCE 1L
#endif
/**
- * _BSD_SOURCE || _SVID_SOURCE implies _POSIX_C_SOURCE = 2.
+ * _GNU_SOURCE implies _XOPEN_SOURCE = 500.
*/
-#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE)
-# if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE < 1L)
-# undef _POSIX_C_SOURCE
+#if defined(__GNU_SOURCE)
+# if __XOPEN_SOURCE <= 499L
+# undef __XOPEN_SOURCE
# endif
-# if !defined(_POSIX_C_SOURCE)
-# define _POSIX_C_SOURCE 2
+# if !defined(__XOPEN_SOURCE)
+# define __XOPEN_SOURCE 500L
# endif
#endif
/**
- * _SVID_SOURCE implies _XOPEN_SOURCE
+ * _XOPEN_SOURCE >= 500 implies _XOPEN_SOURCE_EXTENDED.
*/
-#if defined(_SVID_SOURCE) && !defined(_XOPEN_SOURCE)
-# define _XOPEN_SOURCE 1
+#if (__XOPEN_SOURCE >= 500L) && !defined(__XOPEN_SOURCE_EXTENDED)
+# define __XOPEN_SOURCE_EXTENDED 1L
#endif
/**
- * _BSD_COMPATIBLE_SOURCE requires _BSD_SOURCE.
+ * _XOPEN_SOURCE_EXTENDED implies _XOPEN_SOURCE.
*/
-#if defined(_BSD_COMPATIBLE_SOURCE) && !defined(_BSD_SOURCE)
-# if !defined(_SLIBC_SUPPRESS_WARNINGS)
-# warning "_BSD_COMPATIBLE_SOURCE is defined, but _BSD_SOURCE is undefined."
-# endif
+#if defined(__XOPEN_SOURCE_EXTENDED) && !defined(__XOPEN_SOURCE)
+# define __XOPEN_SOURCE 1L
#endif
/**
- * _BSD_COMPATIBLE_SOURCE and _POSIX_COMPATIBLE_SOURCE
- * are incompatible.
+ * _XOPEN_SOURCE implies _POSIX_C_SOURCE = 2.
*/
-#if defined(_BSD_COMPATIBLE_SOURCE) && defined(_POSIX_COMPATIBLE_SOURCE)
-# if !defined(_SLIBC_SUPPRESS_WARNINGS)
-# warning "You should not define both _BSD_COMPATIBLE_SOURCE and _POSIX_COMPATIBLE_SOURCE."
+#if defined(__XOPEN_SOURCE)
+# if __POSIX_C_SOURCE <= 1L
+# undef __POSIX_C_SOURCE
+# endif
+# if !defined(__POSIX_C_SOURCE)
+# define __POSIX_C_SOURCE 2L
# endif
#endif
-
/**
- * Feature-test macros that also change that
- * `_PORTABLE_SOURCE` and `_LIBRARY_HEADER`
- * is not defined.
+ * _POSIX_SOURCE is implied if _POSIX_C_SOURCE >= 1.
*/
-#if !defined(__PORTABLE)
-# if defined(_GNU_SOURCE)
-# define __GNU_SOURCE _GNU_SOURCE
-# endif
-# if defined(_SLIBC_SOURCE)
-# define __SLIBC_SOURCE _SLIBC_SOURCE
-# endif
-# if defined(_BSD_SOURCE)
-# define __BSD_SOURCE _BSD_SOURCE
-# endif
-# if defined(_XOPEN_SOURCE)
-# define __XOPEN_SOURCE _XOPEN_SOURCE
-# endif
-# if defined(_ISOC11_SOURCE)
-# define __ISOC11_SOURCE _ISOC11_SOURCE
-# endif
-#endif
-#if defined(_POSIX_SOURCE)
-# define __POSIX_SOURCE _POSIX_SOURCE
+#if !defined(__POSIX_SOURCE) && (__POSIX_C_SOURCE >= 1L)
+# define __POSIX_SOURCE 1L
#endif
-#if defined(_POSIX_C_SOURCE)
-# define __POSIX_C_SOURCE _POSIX_C_SOURCE
+#if (__POSIX_C_SOURCE <= 0) && !defined(__POSIX_SOURCE)
+# define __POSIX_C_SOURCE 1L
#endif
-
-
/**
- * Macro used to exclude code unless GCC is used.
+ * _GNU_SOURCE implies _ISOC89_SOURCE.
*/
-#if defined(__GNUC__)
-# define __GCC_ONLY(...) __VA_ARGS__
-#else
-# define __GCC_ONLY(...) /* ignore */
+#if defined(__GNU_SOURCE) && !defined(__ISOC89_SOURCE)
+# define __ISOC89_SOURCE
#endif
-
/**
- * Specifies that a function never returns, that is,
- * the process exits before the function returns.
+ * _GNU_SOURCE implies _ISOC90_SOURCE.
*/
-#if !defined(__C11__) && defined(__GNUC__)
-# define __noreturn __attribute__((noreturn))
-#elif defined(__C11__)
-# define __noreturn _Noreturn
-#else
-# define __noreturn /* ignore */
+#if defined(__GNU_SOURCE) && !defined(__ISOC90_SOURCE)
+# define __ISOC90_SOURCE
#endif
-
/**
- * Macro used to exclude code unless `_SLIBC_SOURCE` is set.
+ * _GNU_SOURCE implies _ISOC95_SOURCE.
*/
-#if defined(_SLIBC_SOURCE)
-# define __SLIBC_ONLY(...) __VA_ARGS__
-#else
-# define __SLIBC_ONLY(...) /* ignore */
+#if defined(__GNU_SOURCE) && !defined(__ISOC95_SOURCE)
+# define __ISOC95_SOURCE
#endif
-
/**
- * Mark a function, variable or type as deprecated,
- * with a message that tells the user why the the
- * function is deprecated, or functions to use instead.
+ * _GNU_SOURCE implies _ISOC99_SOURCE.
*/
-#if !defined(_SLIBC_SUPPRESS_WARNINGS)
-# define __deprecated(msg) __GCC_ONLY(__attribute__((deprecated(msg))))
-#else
-# define __deprecated(msg) /* ignore */
+#if defined(__GNU_SOURCE) && !defined(__ISOC99_SOURCE)
+# define __ISOC99_SOURCE
#endif
-
/**
- * Warn if a function, variable or type is used.
+ * _GNU_SOURCE implies _LARGEFILE_SOURCE.
*/
-#if !defined(_SLIBC_SUPPRESS_WARNINGS)
-# define __warning(msg) __GCC_ONLY(__attribute__((warning(msg))))
-# define __slibc_warning(msg) __SLIBC_ONLY(__warning(msg))
-#else
-# define __warning(msg) /* ignore */
-# define __slibc_warning(msg) /* ignore */
+#if defined(__GNU_SOURCE) && !defined(__LARGEFILE_SOURCE)
+# define __LARGEFILE_SOURCE 1L
#endif
-
/**
- * Functions that have a BSD-specification that is conficting
- * with the POSIX-specification shall have this attribute.
+ * _GNU_SOURCE implies _LARGEFILE64_SOURCE.
*/
-#if defined(_BSD_SOURCE) && !defined(_POSIX_COMPATIBLE_SOURCE) && !defined(_BSD_COMPATIBLE_SOURCE)
-# define __bsd_posix_conflict \
- __warning("The BSD-version of this function is incompatible with the POSIX-version.")
-#else
-# define __bsd_posix_conflict /* ignore*/
+#if defined(__GNU_SOURCE) && !defined(__LARGEFILE64_SOURCE)
+# define __LARGEFILE64_SOURCE 1L
#endif
-
/**
- * Format for the `format` GCC function attribute,
- * for `*printf` functions.
+ * _GNU_SOURCE implies _ATFILE_SOURCE.
*/
-#define slibc_printf printf /* TODO write GCC extension */
-
-/**
- * Format for the `format` GCC function attribute,
- * for `*scanf` functions.
- */
-#define slibc_scanf scanf /* TODO write GCC extension */
-
+#if defined(__GNU_SOURCE) && !defined(__ATFILE_SOURCE)
+# define __ATFILE_SOURCE 1L
+#endif
#endif
diff --git a/include/slibc/portability.h b/include/slibc/portability.h
new file mode 100644
index 0000000..5eae353
--- /dev/null
+++ b/include/slibc/portability.h
@@ -0,0 +1,195 @@
+/**
+ * slibc — Yet another C library
+ * Copyright © 2015 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/* This file should be included from and only from <slibc/features.h>. */
+/* These definitions are only to be used in slibc header-files. */
+
+
+/* Clear old definitions. */
+#ifdef __PORTABLE
+# undef __PORTABLE
+#endif
+#ifdef __ISOC89_SOURCE
+# undef __ISOC89_SOURCE
+#endif
+#ifdef __ISOC90_SOURCE
+# undef __ISOC90_SOURCE
+#endif
+#ifdef __ISOC95_SOURCE
+# undef __ISOC95_SOURCE
+#endif
+#ifdef __ISOC99_SOURCE
+# undef __ISOC99_SOURCE
+#endif
+#ifdef __ISOC11_SOURCE
+# undef __ISOC11_SOURCE
+#endif
+#ifdef __POSIX_SOURCE
+# undef __POSIX_SOURCE
+#endif
+#ifdef __POSIX_C_SOURCE
+# undef __POSIX_C_SOURCE
+#endif
+#ifdef __SVID_SOURCE
+# undef __SVID_SOURCE
+#endif
+#ifdef __XOPEN_SOURCE
+# undef __XOPEN_SOURCE
+#endif
+#ifdef __XOPEN_SOURCE_EXTENDED
+# undef __XOPEN_SOURCE_EXTENDED
+#endif
+#ifdef __SUS_SOURCE
+# undef __SUS_SOURCE
+#endif
+#ifdef __GNU_SOURCE
+# undef __GNU_SOURCE
+#endif
+#ifdef __DEFAULT_SOURCE
+# undef __DEFAULT_SOURCE
+#endif
+#ifdef __ATFILE_SOURCE
+# undef __ATFILE_SOURCE
+#endif
+#ifdef __LARGEFILE_SOURCE
+# undef __LARGEFILE_SOURCE
+#endif
+#ifdef __LARGEFILE64_SOURCE
+# undef __LARGEFILE64_SOURCE
+#endif
+#ifdef __FILE_OFFSET_BITS
+# undef __FILE_OFFSET_BITS
+#endif
+#ifdef __REENTRANT
+# undef __REENTRANT
+#endif
+
+
+
+
+/**
+ * Macro that is defined if portability shall be ensured.
+ */
+#if defined(_PORTABLE_SOURCE) || defined(_LIBRARY_HEADER)
+# define __PORTABLE
+#endif
+
+/**
+ * Internal feature-test macros that also check
+ * that `_PORTABLE_SOURCE` and `_LIBRARY_HEADER`
+ * is not defined.
+ */
+#if !defined(__PORTABLE)
+# if defined(_GNU_SOURCE)
+# define __GNU_SOURCE _GNU_SOURCE
+# endif
+# if defined(_SLIBC_SOURCE)
+# define __SLIBC_SOURCE _SLIBC_SOURCE
+# endif
+# if defined(_BSD_SOURCE)
+# define __BSD_SOURCE _BSD_SOURCE
+# endif
+# if defined(_XOPEN_SOURCE)
+# define __XOPEN_SOURCE (_XOPEN_SOURCE - 0L)
+# endif
+# if defined(_XOPEN_SOURCE_EXTENDED)
+# define __XOPEN_SOURCE_EXTENDED _XOPEN_SOURCE_EXTENDED
+# endif
+# if defined(_ISOC11_SOURCE)
+# define __ISOC11_SOURCE _ISOC11_SOURCE
+# endif
+# if defined(_ATFILE_SOURCE)
+# define __ATFILE_SOURCE _ATFILE_SOURCE
+# endif
+# if defined(_DEFAULT_SOURCE)
+# define __DEFAULT_SOURCE _DEFAULT_SOURCE
+# endif
+# if defined(_LARGEFILE_SOURCE)
+# define __LARGEFILE_SOURCE _LARGEFILE_SOURCE
+# endif
+# if defined(_LARGEFILE64_SOURCE)
+# define __LARGEFILE64_SOURCE _LARGEFILE64_SOURCE
+# endif
+# if defined(_FILE_OFFSET_BITS)
+# define __FILE_OFFSET_BITS _FILE_OFFSET_BITS
+# endif
+# if defined(_REENTRANT) || defined(_THREADSAFE)
+# define __REENTRANT 1L
+# endif
+#endif
+
+/**
+ * Internal feature-test macros that also check that
+ * not check `_PORTABLE_SOURCE` or `_LIBRARY_HEADER`.
+ */
+#if defined(_POSIX_SOURCE)
+# define __POSIX_SOURCE _POSIX_SOURCE
+#endif
+#if defined(_POSIX_C_SOURCE)
+# define __POSIX_C_SOURCE _POSIX_C_SOURCE
+#endif
+#if defined(_ISOC89_SOURCE)
+# define __ISOC89_SOURCE _ISOC89_SOURCE
+#endif
+#if defined(_ISOC90_SOURCE)
+# define __ISOC90_SOURCE _ISOC90_SOURCE
+#endif
+#if defined(_ISOC95_SOURCE)
+# define __ISOC95_SOURCE _ISOC95_SOURCE
+#endif
+#if defined(_ISOC11_SOURCE)
+# define __ISOC99_SOURCE _ISOC99_SOURCE
+#endif
+
+
+/**
+ * _POSIX_C_SOURCE has no effect if it is
+ * zero, set it to zero if it is undefined.
+ */
+#if !defined(__POSIX_C_SOURCE)
+# define __POSIX_C_SOURCE 0L
+#endif
+
+/**
+ * Add __SUS_SOURCE as an alias for
+ * __XOPEN_SOURCE >= 500, to simplify
+ * feature tests
+ */
+#if defined(__XOPEN_SOURCE) && (__XOPEN_SOURCE >= 500)
+# define __SUS_SOURCE 1L
+#endif
+
+
+/**
+ * _BSD_COMPATIBLE_SOURCE requires _BSD_SOURCE.
+ */
+#if defined(_BSD_COMPATIBLE_SOURCE) && !defined(_BSD_SOURCE)
+# if !defined(_SLIBC_SUPPRESS_WARNINGS)
+# warning "_BSD_COMPATIBLE_SOURCE is defined, but _BSD_SOURCE is undefined."
+# endif
+#endif
+
+/**
+ * _BSD_COMPATIBLE_SOURCE and _POSIX_COMPATIBLE_SOURCE
+ * are incompatible.
+ */
+#if defined(_BSD_COMPATIBLE_SOURCE) && defined(_POSIX_COMPATIBLE_SOURCE)
+# if !defined(_SLIBC_SUPPRESS_WARNINGS)
+# warning "You should not define both _BSD_COMPATIBLE_SOURCE and _POSIX_COMPATIBLE_SOURCE."
+# endif
+#endif
+