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:
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() */