Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags
author: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 committer: kx <kx@radix-linux.su> 2024-12-20 16:11:07 +0300 commit: 868b2b66b564b5c00e3a74d10be45db7151627ac parent: cce2ae8d3312493b7653358bb4af201d3271377b
Commit Summary:
Version 1.0.14
Diffstat:
1 file changed, 178 insertions, 0 deletions
diff --git a/mpu/mpu-warning.c b/mpu/mpu-warning.c
new file mode 100644
index 0000000..60c314e
--- /dev/null
+++ b/mpu/mpu-warning.c
@@ -0,0 +1,225 @@
+
+/***************************************************************
+  __MPU_WARNING.C
+
+       This file contains source code of functions for
+       MPU extra warnings operations.
+
+       PART OF : MPU - library .
+
+       USAGE   : Internal only .
+
+       NOTE    : NONE .
+
+       Copyright (C) 2000 - 2024  by Andrew V.Kosteltsev.
+       All Rights Reserved.
+ ***************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <nls.h>
+
+#include <errno.h>   /* errno(3)  */
+#include <string.h>  /* strcpy(3) */
+#include <strings.h> /* bzero(3)  */
+#include <stdlib.h>
+#include <stdio.h>
+#include <locale.h>
+
+#include <libmpu.h>
+#include <mpu-context.h>
+
+#include <mpu-emutype.h>
+#include <mpu-integer.h>
+#include <mpu-real.h>
+#include <mpu-floatp.h>
+#include <mpu-ioreal.h>
+
+#include <mpu-char.h>
+#include <mpu-symbols.h>
+
+#include <mpu-math-errno.h>
+#include <mpu-mtherr.h>
+
+/*
+  __mpu_warning() работает с внешним форматом чисел.
+
+  Данная вункция вызывается только в том случае,
+  когда переменная __extra_warnings имеет значение
+  отличное от нуля.
+
+  Пользователь может определить собственную функцию
+  __mpu_warning() в качестве замены данного стандартного
+  обработчика вывода дополнительных предупреждений.
+ */
+
+#define         MSG_FORMAT "message:  %0.4d: %s(): %s" /* type, name, msg */
+#define   ERROR_MSG_FORMAT   "error: E%0.4d: %s(): %s" /* type, name, msg */
+#define WARNING_MSG_FORMAT "warning: W%0.4d: %s(): %s" /* type, name, msg */
+
+
+int __use_default_mpu_warning = 1;
+
+void __mpu_warning( struct __exception *pexcept )
+{
+  __mpu_char8_t                 str[MPU_MATH_ERROR_MSG_SIZE];
+  __mpu_char8_t    error_msg_format[MPU_MATH_ERROR_MSG_SIZE];
+  __mpu_char8_t  warning_msg_format[MPU_MATH_ERROR_MSG_SIZE];
+  __mpu_char8_t                 fmt[MPU_MATH_ERROR_MSG_SIZE];
+
+  /************************************************************
+    Floating point exception.
+    ==========================================================
+    Исключение операции с плавающей точкой.
+   ************************************************************/
+  __mpu_char8_t *exception = (__mpu_char8_t *)N_("Floating point exception");
+  /************************************************************
+    Unknown message source.
+    ==========================================================
+    Неизвестный источник сообщения.
+   ************************************************************/
+  __mpu_char8_t *unknown   = (__mpu_char8_t *)N_("Unknown message source");
+
+#if ENABLE_NLS == 1
+    char   *back_locale = NULL;
+    char   *lt          = NULL;
+    char   *back_env    = NULL;
+
+    /*******************************************************
+      Так как gettext в первую очередь проверяет LC_ALL,
+      затем LC_MESSAGE и в процессе работы пользуется
+      LC_CTYPE, мы для простоты временно выставляем LC_ALL.
+      Использование LC_MESSAGE при отличном от него LC_ALL
+      нам ничего не даст.
+     *******************************************************/
+    back_locale = setlocale( LC_ALL, (const char *)NULL );
+    lt = setlocale( LC_ALL, (const char *)"ru" );
+
+    back_env = getenv( (const char *)"LANGUAGE" );
+    (void)setenv( (const char *)"LANGUAGE", (const char *)"ru", 1 /* 1 - overwrite */ );
+
+    exception = (__mpu_char8_t *)dgettext( PACKAGE, (const char *)exception );
+    unknown   = (__mpu_char8_t *)dgettext( PACKAGE, (const char *)unknown );
+#endif
+
+  strcpy(   (char *)&error_msg_format[0],   ERROR_MSG_FORMAT );
+  strcpy( (char *)&warning_msg_format[0], WARNING_MSG_FORMAT );
+
+  /*******************************************************
+    ERRNO FOR MESSAGES:
+       _INTEGER_ + 1000, _REAL_ + 2000, _COMPLEX_ + 3000.
+    MESSAGES TYPE:
+       TRUE - error; FALSE - warning.
+   *******************************************************/
+  switch( pexcept->who )
+  {
+    case _INTEGER_:
+      pexcept->type = __integer_error_no;
+      sprintf( (char *)&str[0],
+               (pexcept->msg_type) ? (error_msg_format) :
+                                     (warning_msg_format),
+               pexcept->type + 1000, (char *)pexcept->name, (char *)pexcept->msg );
+      break;
+
+    case    _REAL_:
+      pexcept->type = __real_error_no;
+      sprintf( (char *)&str[0],
+               (pexcept->msg_type) ? (error_msg_format) :
+                                     (warning_msg_format),
+               pexcept->type + 2000, (char *)pexcept->name, (char *)pexcept->msg );
+      break;
+
+    case _COMPLEX_:
+      pexcept->type = __complex_error_no;
+      sprintf( (char *)&str[0],
+               (pexcept->msg_type) ? (error_msg_format) :
+                                     (warning_msg_format),
+               pexcept->type + 3000, (char *)pexcept->name, (char *)pexcept->msg );
+      break;
+
+    case    _MATH_:
+      {
+        __mpu_char8_t    s[REAL_131072_MAX_STRING]; /* mpu-floatp.h */
+        __mpu_char8_t  num[REAL_131072_MAX_STRING];
+        __mpu_char8_t   st[MPU_MATH_ERROR_MSG_SIZE];
+
+        EMUSHORT       eic[NPIR_131072];
+        int            n_bits;
+
+        /* Type the string STR[] */
+        if( pexcept->arg_1 )
+        {
+          n_bits = pexcept->nb_a1 * BITS_PER_BYTE;
+
+          unpack( (EMUSHORT *)&eic[0], (EMUSHORT *)pexcept->arg_1, n_bits );
+
+          ei_real_to_ascii( (__mpu_char8_t *)&s[0],
+                            (EMUSHORT *)&eic[0],
+                            (_get_ndec( pexcept->nb_a1 ) < 12) ? _get_ndec( pexcept->nb_a1 ): 12,
+                            'E', 0, 0, n_bits );
+
+          strcpy( (char *)&num[0], (char *)&s[0] );
+          strcpy( (char *)&fmt[0], exception );
+          strcat( (char *)&fmt[0], ": %s( %s" );
+          sprintf( (char *)&str[0], (const char *)&fmt[0], (char *)pexcept->name, (char *)&num[0] );
+        }
+        else
+        {
+          strcpy( (char *)&fmt[0], exception );
+          strcat( (char *)&fmt[0], ": %s( " );
+          sprintf( (char *)&str[0], (const char *)&fmt[0], (char *)pexcept->name );
+        }
+
+        if( pexcept->arg_2 )
+        {
+          n_bits = pexcept->nb_a2 * BITS_PER_BYTE;
+
+          unpack( (EMUSHORT *)&eic[0], (EMUSHORT *)pexcept->arg_2, n_bits );
+
+          ei_real_to_ascii( (__mpu_char8_t *)&s[0],
+                            (EMUSHORT *)&eic[0],
+                            (_get_ndec( pexcept->nb_a2 ) < 12) ? _get_ndec( pexcept->nb_a2 ): 12,
+                            'E', 0, 0, n_bits );
+
+          strcpy( (char *)&num[0], (char *)&s[0] );
+          strcpy( (char *)&fmt[0], ", %s ): %s" );
+          sprintf( (char *)&st[0], (const char *)&fmt[0], (char *)&num[0], (char *)pexcept->msg );
+          strcat( (char *)&str[0], (char *)&st[0] );
+        }
+        else
+        {
+          strcpy( (char *)&fmt[0], " ): %s" );
+          sprintf( (char *)&st[0], (const char *)&fmt[0], (char *)pexcept->msg );
+          strcat( (char *)&str[0], (char *)&st[0] );
+        }
+      }
+      break;
+
+    default:
+      {
+        strcpy( (char *)&fmt[0], unknown );
+        strcat( (char *)&fmt[0], ": %0.4d: %s(): %s" );
+        sprintf( (char *)&str[0], (const char *)&fmt[0], pexcept->type, (char *)pexcept->name, (char *)pexcept->msg );
+      }
+      break;
+
+  } /* End switch( pexcept->who ) */
+
+  strcpy( (char *)&fmt[0], "%s.\n" );
+
+  fprintf( stderr, (const char *)&fmt[0], (char *)&str[0] );
+
+#if ENABLE_NLS == 1
+  /* restore locale and environment */
+  if( back_locale )
+    (void)setlocale( LC_ALL, (const char *)back_locale );
+
+  if( back_env )
+    (void)setenv( (const char *)"LANGUAGE", (const char *)back_env, 1 /* 1 - overwrite */ );
+#endif
+
+  return;
+
+} /* End of __mpu_warning() */