Miscellaneous 'sendfile' fixes and improved tests.
[bpt/guile.git] / libguile / __scm.h
index 55f9f49..ed35d53 100644 (file)
@@ -3,7 +3,8 @@
 #ifndef SCM___SCM_H
 #define SCM___SCM_H
 
-/* Copyright (C) 1995,1996,1998,1999,2000,2001,2002,2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2006,
+ *   2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
  * additional information to the developers.
  */
 
+/* Return true (non-zero) if GCC version MAJ.MIN or later is being used
+ * (macro taken from glibc.)  */
+#if defined __GNUC__ && defined __GNUC_MINOR__
+# define SCM_GNUC_PREREQ(maj, min) \
+       ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define SCM_GNUC_PREREQ(maj, min) 0
+#endif
+
 /* The macro SCM_NORETURN indicates that a function will never return.
  * Examples:
  *   1) int foo (char arg) SCM_NORETURN;
@@ -89,7 +99,7 @@
 /* The SCM_EXPECT macros provide branch prediction hints to the compiler.  To
  * use only in places where the result of the expression under "normal"
  * circumstances is known.  */
-#if defined(__GNUC__) && (__GNUC__ >= 3)
+#if SCM_GNUC_PREREQ (3, 0)
 # define SCM_EXPECT    __builtin_expect
 #else
 # define SCM_EXPECT(_expr, _value) (_expr)
  * or variables.  Defining `SCM_BUILDING_DEPRECATED_CODE' allows deprecated
  * functions to be implemented in terms of deprecated functions, and allows
  * deprecated functions to be referred to by `scm_c_define_gsubr ()'.  */
-#if !defined (SCM_BUILDING_DEPRECATED_CODE)    \
-    && defined (__GNUC__) && (__GNUC__ >= 3)
+#if !defined (SCM_BUILDING_DEPRECATED_CODE) && SCM_GNUC_PREREQ (3, 0)
 # define SCM_DEPRECATED  SCM_API __attribute__ ((__deprecated__))
 #else
 # define SCM_DEPRECATED  SCM_API
 #endif
 
+/* The SCM_ALIGNED macro, when defined, can be used to instruct the compiler
+ * to honor the given alignment constraint.  */
+/* Sun Studio supports alignment since Sun Studio 12 */
+#if defined __GNUC__ || (defined( __SUNPRO_C ) && (__SUNPRO_C - 0 >= 0x590))
+# define SCM_ALIGNED(x)  __attribute__ ((aligned (x)))
+#elif defined __INTEL_COMPILER
+# define SCM_ALIGNED(x)  __declspec (align (x))
+#else
+/* Don't know how to align things.  */
+# undef SCM_ALIGNED
+#endif
+
+/* The SCM_MALLOC macro can be used in function declarations to tell the
+ * compiler that a function may be treated as if any non-NULL pointer it returns
+ * cannot alias any other pointer valid when the function returns.  */
+#if SCM_GNUC_PREREQ (3, 0)
+# define SCM_MALLOC  __attribute__ ((__malloc__))
+#else
+# define SCM_MALLOC
+#endif
 
 \f
 /* {Supported Options}
 
 /* #define GUILE_DEBUG_FREELIST */
 
-/* All the number support there is.
- */
-#define BIGNUMS
-
-/* GC should relinquish empty cons-pair arenas. */
-/* cmm:FIXME look at this after done mangling the GC */
-/* #define GC_FREE_SEGMENTS */
-
-/* Provide a scheme-accessible count-down timer that
- * generates a pseudo-interrupt.
- */
-#define TICKS
-
 
 /* Use engineering notation when converting numbers strings?
  */
 /* SCM_API is a macro prepended to all function and data definitions
    which should be exported from libguile. */
 
-#if BUILDING_LIBGUILE && HAVE_VISIBILITY
+#if defined BUILDING_LIBGUILE && defined HAVE_VISIBILITY
 # define SCM_API extern __attribute__((__visibility__("default")))
-#elif BUILDING_LIBGUILE && defined _MSC_VER
+#elif defined BUILDING_LIBGUILE && defined _MSC_VER
 # define SCM_API __declspec(dllexport) extern
 #elif defined _MSC_VER
 # define SCM_API __declspec(dllimport) extern
 
 \f
 
+/* We would like gnu89 extern inline semantics, not C99 extern inline
+   semantics, so that we can be sure to avoid reifying definitions of
+   inline functions in all compilation units, which is a possibility at
+   low optimization levels, or if a user takes the address of an inline
+   function.
+
+   Hence the `__gnu_inline__' attribute, in accordance with:
+   http://gcc.gnu.org/gcc-4.3/porting_to.html .
+
+   With GCC 4.2, `__GNUC_STDC_INLINE__' is never defined (because C99 inline
+   semantics are not supported), but a warning is issued in C99 mode if
+   `__gnu_inline__' is not used.
+
+   Apple's GCC build >5400 (since Xcode 3.0) doesn't support GNU inline in
+   C99 mode and doesn't define `__GNUC_STDC_INLINE__'.  Fall back to "static
+   inline" in that case.  */
+
+# if (defined __GNUC__) && (!(((defined __APPLE_CC__) && (__APPLE_CC__ > 5400)) && __STDC_VERSION__ >= 199901L))
+#  if (defined __GNUC_STDC_INLINE__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 2)
+#   define SCM_C_EXTERN_INLINE                                 \
+           extern __inline__ __attribute__ ((__gnu_inline__))
+#  else
+#   define SCM_C_EXTERN_INLINE extern __inline__
+#  endif
+# endif
+
+/* SCM_INLINE is a macro prepended to all public inline function
+   declarations.  Implementations of those functions should also be in
+   the header file, prefixed by SCM_INLINE_IMPLEMENTATION, and protected
+   by SCM_CAN_INLINE and a CPP define for the C file in question, like
+   SCM_INLINE_C_INCLUDING_INLINE_H.  See inline.h for an example
+   usage.  */
+
+#if defined SCM_IMPLEMENT_INLINES
+/* Reifying functions to a file, whether or not inlining is available.  */
+# define SCM_CAN_INLINE 0
+# define SCM_INLINE SCM_API
+# define SCM_INLINE_IMPLEMENTATION
+#elif defined SCM_C_INLINE
+/* Declarations when inlining is available.  */
+# define SCM_CAN_INLINE 1
+# ifdef SCM_C_EXTERN_INLINE
+#  define SCM_INLINE SCM_C_EXTERN_INLINE
+# else
+/* Fall back to static inline if GNU "extern inline" is unavailable.  */
+#  define SCM_INLINE static SCM_C_INLINE
+# endif
+# define SCM_INLINE_IMPLEMENTATION SCM_INLINE
+#else
+/* Declarations when inlining is not available.  */
+# define SCM_CAN_INLINE 0
+# define SCM_INLINE SCM_API
+/* Don't define SCM_INLINE_IMPLEMENTATION; it should never be seen in
+   this case.  */
+#endif
+
+\f
+
 /* {Debugging Options}
  *
  * These compile time options determine whether to include code that is only
 #ifdef LONG_BIT
 # define SCM_LONG_BIT LONG_BIT
 #else
-# define SCM_LONG_BIT (SCM_CHAR_BIT * sizeof (long) / sizeof (char))
-#endif
-
-#ifdef UCHAR_MAX
-# define SCM_CHAR_CODE_LIMIT (UCHAR_MAX + 1L)
-#else
-# define SCM_CHAR_CODE_LIMIT 256L
+# define SCM_LONG_BIT (SCM_SIZEOF_LONG * 8)
 #endif
 
 #define SCM_I_UTYPE_MAX(type)      ((type)-1)
 #define SCM_T_INT32_MIN   SCM_I_TYPE_MIN(scm_t_int32,SCM_T_UINT32_MAX)
 #define SCM_T_INT32_MAX   SCM_I_TYPE_MAX(scm_t_int32,SCM_T_UINT32_MAX)
 
-#if SCM_HAVE_T_INT64
 #define SCM_T_UINT64_MAX  SCM_I_UTYPE_MAX(scm_t_uint64)
 #define SCM_T_INT64_MIN   SCM_I_TYPE_MIN(scm_t_int64,SCM_T_UINT64_MAX)
 #define SCM_T_INT64_MAX   SCM_I_TYPE_MAX(scm_t_int64,SCM_T_UINT64_MAX)
-#endif
 
 #if SCM_SIZEOF_LONG_LONG
 #define SCM_I_ULLONG_MAX  SCM_I_UTYPE_MAX(unsigned long long)
 #define SCM_T_INTMAX_MIN  SCM_I_TYPE_MIN(scm_t_intmax,SCM_T_UINTMAX_MAX)
 #define SCM_T_INTMAX_MAX  SCM_I_TYPE_MAX(scm_t_intmax,SCM_T_UINTMAX_MAX)
 
+#define SCM_T_UINTPTR_MAX SCM_I_UTYPE_MAX(scm_t_uintptr)
+#define SCM_T_INTPTR_MIN  SCM_I_TYPE_MIN(scm_t_intptr,SCM_T_UINTPTR_MAX)
+#define SCM_T_INTPTR_MAX  SCM_I_TYPE_MAX(scm_t_intptr,SCM_T_UINTPTR_MAX)
+
 #define SCM_I_SIZE_MAX    SCM_I_UTYPE_MAX(size_t)
 #define SCM_I_SSIZE_MIN   SCM_I_TYPE_MIN(ssize_t,SCM_I_SIZE_MAX)
 #define SCM_I_SSIZE_MAX   SCM_I_TYPE_MAX(ssize_t,SCM_I_SIZE_MAX)
 
 #include "libguile/tags.h"
 
+
+/* The type of subrs, i.e., Scheme procedures implemented in C.  Empty
+   function declarators are used internally for pointers to functions of
+   any arity.  However, these are equivalent to `(void)' in C++, are
+   obsolescent as of C99, and trigger `strict-prototypes' GCC warnings
+   (bug #23681).  */
+
+#ifdef BUILDING_LIBGUILE
+typedef SCM (* scm_t_subr) ();
+#else
+typedef void *scm_t_subr;
+#endif
+
 \f
 #ifdef vms
 # ifndef CHEAP_CONTINUATIONS
@@ -497,12 +580,24 @@ SCM_API void scm_async_tick (void);
 #ifdef BUILDING_LIBGUILE
 
 /* FIXME: should change names */
-# define SCM_ASYNC_TICK                                        \
-    do                                                 \
-      {                                                        \
-       if (SCM_I_CURRENT_THREAD->pending_asyncs)       \
-         scm_async_click ();                           \
-      }                                                        \
+# define SCM_ASYNC_TICK                                                 \
+    do                                                                  \
+      {                                                                 \
+       if (SCM_UNLIKELY (SCM_I_CURRENT_THREAD->pending_asyncs))        \
+         scm_async_click ();                                           \
+      }                                                                 \
+    while (0)
+
+/* SCM_ASYNC_TICK_WITH_CODE is only available to Guile itself */
+# define SCM_ASYNC_TICK_WITH_CODE(thr, stmt)                            \
+    do                                                                  \
+      {                                                                 \
+       if (SCM_UNLIKELY (thr->pending_asyncs))                         \
+         {                                                             \
+            stmt;                                                       \
+            scm_async_click ();                                         \
+          }                                                             \
+      }                                                                 \
     while (0)
 
 #else /* !BUILDING_LIBGUILE */
@@ -551,7 +646,6 @@ do { \
 #ifdef SCM_RECKLESS
 #define SCM_ASSERT(_cond, _arg, _pos, _subr)
 #define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg)
-#define SCM_ASRTGO(_cond, _label)
 #else
 #define SCM_ASSERT(_cond, _arg, _pos, _subr)                   \
         do { if (SCM_UNLIKELY (!(_cond)))                      \
@@ -559,9 +653,6 @@ do { \
 #define SCM_ASSERT_TYPE(_cond, _arg, _pos, _subr, _msg)                        \
         do { if (SCM_UNLIKELY (!(_cond)))                              \
           scm_wrong_type_arg_msg(_subr, _pos, _arg, _msg);  } while (0)
-#define SCM_ASRTGO(_cond, _label)              \
-        do {  if (SCM_UNLIKELY (!(_cond)))     \
-          goto _label; } while (0)
 #endif
 
 /*