+ * Some versions of glibc don't expect the C99 inline semantics.
+ */
+fix = {
+ hackname = glibc_c99_inline_1;
+ files = features.h, '*/features.h';
+ select = "^ *&& !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__$";
+ c_fix = format;
+ c_fix_arg = "%0 && (defined __extern_inline || defined __GNUC_GNU_INLINE__)";
+ test_text = <<-EOT
+ #if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
+ && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
+ # define __USE_EXTERN_INLINES 1
+ #endif
+ EOT;
+};
+
+
+/*
+ * Similar, but a version that didn't have __NO_INLINE__
+ */
+fix = {
+ hackname = glibc_c99_inline_1a;
+ files = features.h, '*/features.h';
+ select = "(\\) && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__)\n"
+ "(#[ \t]*define[ \t]*__USE_EXTERN_INLINES[ \t]*1)";
+ c_fix = format;
+ c_fix_arg = "%1 && (defined __extern_inline || defined __GNUC_GNU_INLINE__)\n%2";
+ test_text = <<-EOT
+ #if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ && !defined __OPTIMIZE_SIZE__
+ # define __USE_EXTERN_INLINES 1
+ #endif
+ EOT;
+};
+
+
+/*
+ * The glibc_c99_inline_1 fix should have fixed everything. Unfortunately
+ * there are many glibc headers which do not respect __USE_EXTERN_INLINES.
+ * The remaining glibc_c99_inline_* fixes deal with some of those headers.
+ */
+fix = {
+ hackname = glibc_c99_inline_2;
+ files = sys/stat.h, '*/sys/stat.h';
+ select = "extern __inline__ int";
+ sed = "s/extern int \\(stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int \\1/";
+ sed = "s/extern int \\([lf]stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int \\1/";
+ sed = "s/extern int \\(mknod\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int \\1/";
+ sed = "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\(stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int __REDIRECT\\1 (\\2/";
+ sed = "s/extern int __REDIRECT\\(_NTH\\)\\{0,1\\} (\\([lf]stat\\)/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int __REDIRECT\\1 (\\2/";
+ sed = "s/^extern __inline__ int/"
+ "#ifdef __GNUC_GNU_INLINE__\\\nextern\\\n#endif\\\n"
+ "__inline__ int/";
+ test_text = <<-EOT
+ extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
+ extern __inline__ int
+ __NTH (fstat64 (int __fd, struct stat64 *__statbuf))
+ {}
+ EOT;
+};
+
+
+fix = {
+ hackname = glibc_c99_inline_3;
+ files = bits/string2.h, '*/bits/string2.h';
+ select = "extern __inline";
+ bypass = "__extern_inline|__GNU_STDC_INLINE__";
+ c_fix = format;
+ c_fix_arg = "# if defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)";
+ c_fix_arg = "^# ifdef __cplusplus$";
+ test_text = <<-EOT
+ # ifdef __cplusplus
+ # define __STRING_INLINE inline
+ # else
+ # define __STRING_INLINE extern __inline
+ # endif
+ EOT;
+};
+
+
+fix = {
+ hackname = glibc_c99_inline_4;
+ files = sys/sysmacros.h, '*/sys/sysmacros.h', wchar.h, '*/wchar.h';
+ bypass = "__extern_inline|__gnu_inline__";
+ select = "(^| )extern __inline";
+ c_fix = format;
+ c_fix_arg = "%0 __attribute__ ((__gnu_inline__))";
+ test_text = <<-EOT
+ __extension__ extern __inline unsigned int
+ extern __inline unsigned int
+ EOT;
+};
+
+
+/* glibc-2.3.5 defines pthread mutex initializers incorrectly,
+ * so we replace them with versions that correspond to the
+ * definition.
+ */
+fix = {
+ hackname = glibc_mutex_init;
+ files = pthread.h;
+ select = '\{ *\{ *0, *\} *\}';
+ sed = "/define[ \t]\\{1,\\}PTHREAD_MUTEX_INITIALIZER[ \t]*\\\\/{\n"
+ "N\ns/{ { 0, } }/{ { 0, 0, 0, 0, 0, 0 } }/\n}";
+ sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
+ "\\(RECURSIVE\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0 }/";
+ sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
+ "\\(RECURSIVE\\)_NP\\) }/{ \\1, 0, 0 }/";
+ sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ERRORCHECK\\)_NP\\) }/{ \\1, 0, 0 }/";
+ sed = "s/{ \\(0, 0, 0, PTHREAD_MUTEX_"
+ "\\(ADAPTIVE\\)_NP\\) }/{ \\1, 0, 0 }/";
+ sed = "/define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\/"
+ "N;s/^[ \t]*#[ \t]*"
+ "\\(define[ \t]\\{1,\\}PTHREAD_RWLOCK_INITIALIZER[ \t]*\\\\\\)\\n"
+ "[ \t]*{ { 0, } }/# if __WORDSIZE == 64\\\n"
+ "# \\1\\\n"
+ " { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n"
+ "# else\\\n"
+ "# \\1\\\n"
+ " { { 0, 0, 0, 0, 0, 0, 0, 0 } }\\\n"
+ "# endif/";
+ sed = "s/{ \\(0, 0, 0, 0, 0, 0, "
+ "PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP\\) }/{ \\1, 0 }/";
+ sed = "/define[ \t]\\{1,\\}PTHREAD_COND_INITIALIZER/"
+ "s/{ { 0, } }/{ { 0, 0, 0, 0, 0, (void *) 0, 0, 0 } }/";
+
+ test_text = <<- _EOText_
+ #define PTHREAD_MUTEX_INITIALIZER \\
+ { { 0, } }
+ #ifdef __USE_GNU
+ # if __WORDSIZE == 64
+ # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP } }
+ # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP } }
+ # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP } }
+ # else
+ # define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP } }
+ # define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP } }
+ # define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP \\
+ { { 0, 0, 0, PTHREAD_MUTEX_ADAPTIVE_NP } }
+ # endif
+ #endif
+ # define PTHREAD_RWLOCK_INITIALIZER \\
+ { { 0, } }
+ # ifdef __USE_GNU
+ # if __WORDSIZE == 64
+ # define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \\
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \\
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+ # else
+ # define PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP \\
+ { { 0, 0, 0, 0, 0, 0, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP } }
+ # endif
+ # endif
+ #define PTHREAD_COND_INITIALIZER { { 0, } }
+ _EOText_;
+};
+
+
+/* glibc versions before 2.5 have a version of stdint.h that defines
+ UINT8_C and UINT16_C to produce unsigned constants, as do uClibc
+ versions with stdint.h based on those glibc versions. */
+fix = {
+ hackname = glibc_stdint;
+ files = stdint.h;
+ select = "GNU C Library";
+ c_fix = format;
+ c_fix_arg = "# define UINT8_C(c)\tc\n# define UINT16_C(c)\tc";
+ c_fix_arg = "# define UINT8_C\\(c\\)\tc ## U\n# define UINT16_C\\(c\\)\tc ## U";
+ test_text = "/* This file is part of the GNU C Library. */\n# define UINT8_C(c)\tc ## U\n# define UINT16_C(c)\tc ## U";
+};
+
+
+/* Some versions of glibc have a version of bits/string2.h that
+ produces "value computed is not used" warnings from strncpy; fix
+ this definition by using __builtin_strncpy instead as in newer
+ versions. */
+fix = {
+ hackname = glibc_strncpy;
+ files = bits/string2.h;
+ bypass = "__builtin_strncpy";
+ c_fix = format;
+ c_fix_arg = "# define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)";
+ c_fix_arg = "# define strncpy([^\n]*\\\\\n)*[^\n]*";
+ test_text = <<-EOT
+ # define strncpy(dest, src, n) \
+ (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \\
+ ? (strlen (src) + 1 >= ((size_t) (n)) \\
+ ? (char *) memcpy (dest, src, n) \\
+ : strncpy (dest, src, n)) \\
+ : strncpy (dest, src, n)))
+ EOT;
+
+};
+
+/* glibc's tgmath.h relies on an expression that is not an integer
+ constant expression being treated as it was by GCC 4.4 and
+ earlier. */
+fix = {
+ hackname = glibc_tgmath;
+ files = tgmath.h;
+ select = '\(\(\(type\) 0.25\) && \(\(type\) 0.25 - 1\)\)';
+ bypass = "__floating_type\\(type\\) \\\\\n.*__builtin_classify_type";
+ c_fix = format;
+ c_fix_arg = "(__builtin_classify_type ((type) 0) == 8 || (__builtin_classify_type ((type) 0) == 9 && __builtin_classify_type (__real__ ((type) 0)) == 8))";
+ test_text = "# define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1))";
+};
+
+/*