Moved one dir up.
[kopensolaris-gnu/glibc.git] / math / test-fenv.c
index 62a148b..3a5a7ed 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de> and
    Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/wait.h>
+#include <sys/resource.h>
 
 /*
   Since not all architectures might define all exceptions, we define
@@ -85,7 +86,8 @@ test_single_exception (short int exception,
 }
 
 static void
-test_exceptions (const char *test_name, short int exception)
+test_exceptions (const char *test_name, short int exception,
+                int ignore_inexact)
 {
   printf ("Test: %s\n", test_name);
 #ifdef FE_DIVBYZERO
@@ -97,8 +99,9 @@ test_exceptions (const char *test_name, short int exception)
                          "INVALID");
 #endif
 #ifdef FE_INEXACT
-  test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
-                         "INEXACT");
+  if (!ignore_inexact)
+    test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
+                          "INEXACT");
 #endif
 #ifdef FE_UNDERFLOW
   test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
@@ -114,28 +117,29 @@ static void
 print_rounding (int rounding)
 {
 
-  switch (rounding) {
+  switch (rounding)
+    {
 #ifdef FE_TONEAREST
-  case FE_TONEAREST:
-    printf ("TONEAREST");
-    break;
+    case FE_TONEAREST:
+      printf ("TONEAREST");
+      break;
 #endif
 #ifdef FE_UPWARD
-  case FE_UPWARD:
-    printf ("UPWARD");
-    break;
+    case FE_UPWARD:
+      printf ("UPWARD");
+      break;
 #endif
 #ifdef FE_DOWNWARD
-  case FE_DOWNWARD:
-    printf ("DOWNWARD");
-    break;
+    case FE_DOWNWARD:
+      printf ("DOWNWARD");
+      break;
 #endif
 #ifdef FE_TOWARDZERO
-  case FE_TOWARDZERO:
-    printf ("TOWARDZERO");
-    break;
+    case FE_TOWARDZERO:
+      printf ("TOWARDZERO");
+      break;
 #endif
-  }
+    }
   printf (".\n");
 }
 
@@ -151,11 +155,12 @@ test_rounding (const char *test_name, int rounding_mode)
       printf ("  Pass: Rounding mode is ");
       print_rounding (curr_rounding);
     }
-  else {
-    ++count_errors;
-    printf ("  Fail: Rounding mode is ");
-    print_rounding (curr_rounding);
-  }
+  else
+    {
+      ++count_errors;
+      printf ("  Fail: Rounding mode is ");
+      print_rounding (curr_rounding);
+    }
 }
 
 
@@ -163,28 +168,32 @@ static void
 set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
 {
   char str[200];
+  /* The standard allows the inexact exception to be set together with the
+     underflow and overflow exceptions.  So ignore the inexact flag if the
+     others are raised.  */
+  int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest not set");
   feclearexcept (FE_ALL_EXCEPT);
   feraiseexcept (exception);
-  test_exceptions (str, fe_exc);
+  test_exceptions (str, fe_exc, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, rest also unset");
   feclearexcept (exception);
-  test_exceptions (str, NO_EXC);
+  test_exceptions (str, NO_EXC, ignore_inexact);
 
   strcpy (str, test_name);
   strcat (str, ": set flag, with rest set");
   feraiseexcept (FE_ALL_EXCEPT ^ exception);
   feraiseexcept (exception);
-  test_exceptions (str, ALL_EXC);
+  test_exceptions (str, ALL_EXC, 0);
 
   strcpy (str, test_name);
   strcat (str, ": clear flag, leave rest set");
   feclearexcept (exception);
-  test_exceptions (str, ALL_EXC ^ fe_exc);
+  test_exceptions (str, ALL_EXC ^ fe_exc, 0);
 }
 
 static void
@@ -193,12 +202,12 @@ fe_tests (void)
   /* clear all exceptions and test if all are cleared */
   feclearexcept (FE_ALL_EXCEPT);
   test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
-                   NO_EXC);
+                   NO_EXC, 0);
 
   /* raise all exceptions and test if all are raised */
   feraiseexcept (FE_ALL_EXCEPT);
   test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
-                   ALL_EXC);
+                   ALL_EXC, 0);
   feclearexcept (FE_ALL_EXCEPT);
 
 #ifdef FE_DIVBYZERO
@@ -222,15 +231,36 @@ fe_tests (void)
 static void
 feenv_nomask_test (const char *flag_name, int fe_exc)
 {
+#if defined FE_NOMASK_ENV
   int status;
   pid_t pid;
+  fenv_t saved;
+
+  fegetenv (&saved);
+  errno = 0;
+  fesetenv (FE_NOMASK_ENV);
+  status = errno;
+  fesetenv (&saved);
+  if (status == ENOSYS)
+    {
+      printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n");
+      return;
+    }
 
   printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n");
   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
-  fesetenv (FE_NOMASK_ENV);
-  pid = fork  ();
+  pid = fork ();
   if (pid == 0)
     {
+#ifdef RLIMIT_CORE
+      /* Try to avoid dumping core.  */
+      struct rlimit core_limit;
+      core_limit.rlim_cur = 0;
+      core_limit.rlim_max = 0;
+      setrlimit (RLIMIT_CORE, &core_limit);
+#endif
+
+      fesetenv (FE_NOMASK_ENV);
       feraiseexcept (fe_exc);
       exit (2);
     }
@@ -259,6 +289,7 @@ feenv_nomask_test (const char *flag_name, int fe_exc)
        ++count_errors;
       }
   }
+#endif
 }
 
 /* Test that program doesn't abort with default environment */
@@ -270,10 +301,18 @@ feenv_mask_test (const char *flag_name, int fe_exc)
 
   printf ("Test: after fesetenv (FE_DFL_ENV) processes will not abort\n");
   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
-  fesetenv (FE_DFL_ENV);
   pid = fork ();
   if (pid == 0)
     {
+#ifdef RLIMIT_CORE
+      /* Try to avoid dumping core.  */
+      struct rlimit core_limit;
+      core_limit.rlim_cur = 0;
+      core_limit.rlim_max = 0;
+      setrlimit (RLIMIT_CORE, &core_limit);
+#endif
+
+      fesetenv (FE_DFL_ENV);
       feraiseexcept (fe_exc);
       exit (2);
     }
@@ -339,7 +378,7 @@ static void
 initial_tests (void)
 {
   test_exceptions ("Initially all exceptions should be cleared",
-                   NO_EXC);
+                   NO_EXC, 0);
   test_rounding ("Rounding direction should be initalized to nearest",
                  FE_TONEAREST);
 }