868b2b66 (kx 2024-12-20 16:11:07 +0300 1)
868b2b66 (kx 2024-12-20 16:11:07 +0300 2) /***************************************************************
868b2b66 (kx 2024-12-20 16:11:07 +0300 3) __MPU_WARNING.C
868b2b66 (kx 2024-12-20 16:11:07 +0300 4)
868b2b66 (kx 2024-12-20 16:11:07 +0300 5) This file contains source code of functions for
868b2b66 (kx 2024-12-20 16:11:07 +0300 6) MPU extra warnings operations.
868b2b66 (kx 2024-12-20 16:11:07 +0300 7)
868b2b66 (kx 2024-12-20 16:11:07 +0300 8) PART OF : MPU - library .
868b2b66 (kx 2024-12-20 16:11:07 +0300 9)
868b2b66 (kx 2024-12-20 16:11:07 +0300 10) USAGE : Internal only .
868b2b66 (kx 2024-12-20 16:11:07 +0300 11)
868b2b66 (kx 2024-12-20 16:11:07 +0300 12) NOTE : NONE .
868b2b66 (kx 2024-12-20 16:11:07 +0300 13)
868b2b66 (kx 2024-12-20 16:11:07 +0300 14) Copyright (C) 2000 - 2024 by Andrew V.Kosteltsev.
868b2b66 (kx 2024-12-20 16:11:07 +0300 15) All Rights Reserved.
868b2b66 (kx 2024-12-20 16:11:07 +0300 16) ***************************************************************/
868b2b66 (kx 2024-12-20 16:11:07 +0300 17)
868b2b66 (kx 2024-12-20 16:11:07 +0300 18) #ifdef HAVE_CONFIG_H
868b2b66 (kx 2024-12-20 16:11:07 +0300 19) #include <config.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 20) #endif
868b2b66 (kx 2024-12-20 16:11:07 +0300 21)
868b2b66 (kx 2024-12-20 16:11:07 +0300 22) #include <nls.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 23)
868b2b66 (kx 2024-12-20 16:11:07 +0300 24) #include <errno.h> /* errno(3) */
868b2b66 (kx 2024-12-20 16:11:07 +0300 25) #include <string.h> /* strcpy(3) */
868b2b66 (kx 2024-12-20 16:11:07 +0300 26) #include <strings.h> /* bzero(3) */
868b2b66 (kx 2024-12-20 16:11:07 +0300 27) #include <stdlib.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 28) #include <stdio.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 29) #include <locale.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 30)
868b2b66 (kx 2024-12-20 16:11:07 +0300 31) #include <libmpu.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 32) #include <mpu-context.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 33)
868b2b66 (kx 2024-12-20 16:11:07 +0300 34) #include <mpu-emutype.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 35) #include <mpu-integer.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 36) #include <mpu-real.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 37) #include <mpu-floatp.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 38) #include <mpu-ioreal.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 39)
868b2b66 (kx 2024-12-20 16:11:07 +0300 40) #include <mpu-char.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 41) #include <mpu-symbols.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 42)
868b2b66 (kx 2024-12-20 16:11:07 +0300 43) #include <mpu-math-errno.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 44) #include <mpu-mtherr.h>
868b2b66 (kx 2024-12-20 16:11:07 +0300 45)
868b2b66 (kx 2024-12-20 16:11:07 +0300 46) /*
868b2b66 (kx 2024-12-20 16:11:07 +0300 47) __mpu_warning() работает с внешним форматом чисел.
868b2b66 (kx 2024-12-20 16:11:07 +0300 48)
868b2b66 (kx 2024-12-20 16:11:07 +0300 49) Данная вункция вызывается только в том случае,
868b2b66 (kx 2024-12-20 16:11:07 +0300 50) когда переменная __extra_warnings имеет значение
868b2b66 (kx 2024-12-20 16:11:07 +0300 51) отличное от нуля.
868b2b66 (kx 2024-12-20 16:11:07 +0300 52)
868b2b66 (kx 2024-12-20 16:11:07 +0300 53) Пользователь может определить собственную функцию
868b2b66 (kx 2024-12-20 16:11:07 +0300 54) __mpu_warning() в качестве замены данного стандартного
868b2b66 (kx 2024-12-20 16:11:07 +0300 55) обработчика вывода дополнительных предупреждений.
868b2b66 (kx 2024-12-20 16:11:07 +0300 56) */
868b2b66 (kx 2024-12-20 16:11:07 +0300 57)
868b2b66 (kx 2024-12-20 16:11:07 +0300 58) #define MSG_FORMAT "message: %0.4d: %s(): %s" /* type, name, msg */
868b2b66 (kx 2024-12-20 16:11:07 +0300 59) #define ERROR_MSG_FORMAT "error: E%0.4d: %s(): %s" /* type, name, msg */
868b2b66 (kx 2024-12-20 16:11:07 +0300 60) #define WARNING_MSG_FORMAT "warning: W%0.4d: %s(): %s" /* type, name, msg */
868b2b66 (kx 2024-12-20 16:11:07 +0300 61)
868b2b66 (kx 2024-12-20 16:11:07 +0300 62)
868b2b66 (kx 2024-12-20 16:11:07 +0300 63) int __use_default_mpu_warning = 1;
868b2b66 (kx 2024-12-20 16:11:07 +0300 64)
868b2b66 (kx 2024-12-20 16:11:07 +0300 65) void __mpu_warning( struct __exception *pexcept )
868b2b66 (kx 2024-12-20 16:11:07 +0300 66) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 67) __mpu_char8_t str[MPU_MATH_ERROR_MSG_SIZE];
868b2b66 (kx 2024-12-20 16:11:07 +0300 68) __mpu_char8_t error_msg_format[MPU_MATH_ERROR_MSG_SIZE];
868b2b66 (kx 2024-12-20 16:11:07 +0300 69) __mpu_char8_t warning_msg_format[MPU_MATH_ERROR_MSG_SIZE];
868b2b66 (kx 2024-12-20 16:11:07 +0300 70) __mpu_char8_t fmt[MPU_MATH_ERROR_MSG_SIZE];
868b2b66 (kx 2024-12-20 16:11:07 +0300 71)
868b2b66 (kx 2024-12-20 16:11:07 +0300 72) /************************************************************
868b2b66 (kx 2024-12-20 16:11:07 +0300 73) Floating point exception.
868b2b66 (kx 2024-12-20 16:11:07 +0300 74) ==========================================================
868b2b66 (kx 2024-12-20 16:11:07 +0300 75) Исключение операции с плавающей точкой.
868b2b66 (kx 2024-12-20 16:11:07 +0300 76) ************************************************************/
868b2b66 (kx 2024-12-20 16:11:07 +0300 77) __mpu_char8_t *exception = (__mpu_char8_t *)N_("Floating point exception");
868b2b66 (kx 2024-12-20 16:11:07 +0300 78) /************************************************************
868b2b66 (kx 2024-12-20 16:11:07 +0300 79) Unknown message source.
868b2b66 (kx 2024-12-20 16:11:07 +0300 80) ==========================================================
868b2b66 (kx 2024-12-20 16:11:07 +0300 81) Неизвестный источник сообщения.
868b2b66 (kx 2024-12-20 16:11:07 +0300 82) ************************************************************/
868b2b66 (kx 2024-12-20 16:11:07 +0300 83) __mpu_char8_t *unknown = (__mpu_char8_t *)N_("Unknown message source");
868b2b66 (kx 2024-12-20 16:11:07 +0300 84)
868b2b66 (kx 2024-12-20 16:11:07 +0300 85) #if ENABLE_NLS == 1
868b2b66 (kx 2024-12-20 16:11:07 +0300 86) char *back_locale = NULL;
868b2b66 (kx 2024-12-20 16:11:07 +0300 87) char *lt = NULL;
868b2b66 (kx 2024-12-20 16:11:07 +0300 88) char *back_env = NULL;
868b2b66 (kx 2024-12-20 16:11:07 +0300 89)
868b2b66 (kx 2024-12-20 16:11:07 +0300 90) /*******************************************************
868b2b66 (kx 2024-12-20 16:11:07 +0300 91) Так как gettext в первую очередь проверяет LC_ALL,
868b2b66 (kx 2024-12-20 16:11:07 +0300 92) затем LC_MESSAGE и в процессе работы пользуется
868b2b66 (kx 2024-12-20 16:11:07 +0300 93) LC_CTYPE, мы для простоты временно выставляем LC_ALL.
868b2b66 (kx 2024-12-20 16:11:07 +0300 94) Использование LC_MESSAGE при отличном от него LC_ALL
868b2b66 (kx 2024-12-20 16:11:07 +0300 95) нам ничего не даст.
868b2b66 (kx 2024-12-20 16:11:07 +0300 96) *******************************************************/
868b2b66 (kx 2024-12-20 16:11:07 +0300 97) back_locale = setlocale( LC_ALL, (const char *)NULL );
868b2b66 (kx 2024-12-20 16:11:07 +0300 98) lt = setlocale( LC_ALL, (const char *)"ru" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 99)
868b2b66 (kx 2024-12-20 16:11:07 +0300 100) back_env = getenv( (const char *)"LANGUAGE" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 101) (void)setenv( (const char *)"LANGUAGE", (const char *)"ru", 1 /* 1 - overwrite */ );
868b2b66 (kx 2024-12-20 16:11:07 +0300 102)
868b2b66 (kx 2024-12-20 16:11:07 +0300 103) exception = (__mpu_char8_t *)dgettext( PACKAGE, (const char *)exception );
868b2b66 (kx 2024-12-20 16:11:07 +0300 104) unknown = (__mpu_char8_t *)dgettext( PACKAGE, (const char *)unknown );
868b2b66 (kx 2024-12-20 16:11:07 +0300 105) #endif
868b2b66 (kx 2024-12-20 16:11:07 +0300 106)
868b2b66 (kx 2024-12-20 16:11:07 +0300 107) strcpy( (char *)&error_msg_format[0], ERROR_MSG_FORMAT );
868b2b66 (kx 2024-12-20 16:11:07 +0300 108) strcpy( (char *)&warning_msg_format[0], WARNING_MSG_FORMAT );
868b2b66 (kx 2024-12-20 16:11:07 +0300 109)
868b2b66 (kx 2024-12-20 16:11:07 +0300 110) /*******************************************************
868b2b66 (kx 2024-12-20 16:11:07 +0300 111) ERRNO FOR MESSAGES:
868b2b66 (kx 2024-12-20 16:11:07 +0300 112) _INTEGER_ + 1000, _REAL_ + 2000, _COMPLEX_ + 3000.
868b2b66 (kx 2024-12-20 16:11:07 +0300 113) MESSAGES TYPE:
868b2b66 (kx 2024-12-20 16:11:07 +0300 114) TRUE - error; FALSE - warning.
868b2b66 (kx 2024-12-20 16:11:07 +0300 115) *******************************************************/
868b2b66 (kx 2024-12-20 16:11:07 +0300 116) switch( pexcept->who )
868b2b66 (kx 2024-12-20 16:11:07 +0300 117) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 118) case _INTEGER_:
868b2b66 (kx 2024-12-20 16:11:07 +0300 119) pexcept->type = __integer_error_no;
868b2b66 (kx 2024-12-20 16:11:07 +0300 120) sprintf( (char *)&str[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 121) (pexcept->msg_type) ? (error_msg_format) :
868b2b66 (kx 2024-12-20 16:11:07 +0300 122) (warning_msg_format),
868b2b66 (kx 2024-12-20 16:11:07 +0300 123) pexcept->type + 1000, (char *)pexcept->name, (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 124) break;
868b2b66 (kx 2024-12-20 16:11:07 +0300 125)
868b2b66 (kx 2024-12-20 16:11:07 +0300 126) case _REAL_:
868b2b66 (kx 2024-12-20 16:11:07 +0300 127) pexcept->type = __real_error_no;
868b2b66 (kx 2024-12-20 16:11:07 +0300 128) sprintf( (char *)&str[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 129) (pexcept->msg_type) ? (error_msg_format) :
868b2b66 (kx 2024-12-20 16:11:07 +0300 130) (warning_msg_format),
868b2b66 (kx 2024-12-20 16:11:07 +0300 131) pexcept->type + 2000, (char *)pexcept->name, (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 132) break;
868b2b66 (kx 2024-12-20 16:11:07 +0300 133)
868b2b66 (kx 2024-12-20 16:11:07 +0300 134) case _COMPLEX_:
868b2b66 (kx 2024-12-20 16:11:07 +0300 135) pexcept->type = __complex_error_no;
868b2b66 (kx 2024-12-20 16:11:07 +0300 136) sprintf( (char *)&str[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 137) (pexcept->msg_type) ? (error_msg_format) :
868b2b66 (kx 2024-12-20 16:11:07 +0300 138) (warning_msg_format),
868b2b66 (kx 2024-12-20 16:11:07 +0300 139) pexcept->type + 3000, (char *)pexcept->name, (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 140) break;
868b2b66 (kx 2024-12-20 16:11:07 +0300 141)
868b2b66 (kx 2024-12-20 16:11:07 +0300 142) case _MATH_:
868b2b66 (kx 2024-12-20 16:11:07 +0300 143) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 144) __mpu_char8_t s[REAL_131072_MAX_STRING]; /* mpu-floatp.h */
868b2b66 (kx 2024-12-20 16:11:07 +0300 145) __mpu_char8_t num[REAL_131072_MAX_STRING];
868b2b66 (kx 2024-12-20 16:11:07 +0300 146) __mpu_char8_t st[MPU_MATH_ERROR_MSG_SIZE];
868b2b66 (kx 2024-12-20 16:11:07 +0300 147)
868b2b66 (kx 2024-12-20 16:11:07 +0300 148) EMUSHORT eic[NPIR_131072];
868b2b66 (kx 2024-12-20 16:11:07 +0300 149) int n_bits;
868b2b66 (kx 2024-12-20 16:11:07 +0300 150)
868b2b66 (kx 2024-12-20 16:11:07 +0300 151) /* Type the string STR[] */
868b2b66 (kx 2024-12-20 16:11:07 +0300 152) if( pexcept->arg_1 )
868b2b66 (kx 2024-12-20 16:11:07 +0300 153) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 154) n_bits = pexcept->nb_a1 * BITS_PER_BYTE;
868b2b66 (kx 2024-12-20 16:11:07 +0300 155)
868b2b66 (kx 2024-12-20 16:11:07 +0300 156) unpack( (EMUSHORT *)&eic[0], (EMUSHORT *)pexcept->arg_1, n_bits );
868b2b66 (kx 2024-12-20 16:11:07 +0300 157)
868b2b66 (kx 2024-12-20 16:11:07 +0300 158) ei_real_to_ascii( (__mpu_char8_t *)&s[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 159) (EMUSHORT *)&eic[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 160) (_get_ndec( pexcept->nb_a1 ) < 12) ? _get_ndec( pexcept->nb_a1 ): 12,
868b2b66 (kx 2024-12-20 16:11:07 +0300 161) 'E', 0, 0, n_bits );
868b2b66 (kx 2024-12-20 16:11:07 +0300 162)
868b2b66 (kx 2024-12-20 16:11:07 +0300 163) strcpy( (char *)&num[0], (char *)&s[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 164) strcpy( (char *)&fmt[0], exception );
868b2b66 (kx 2024-12-20 16:11:07 +0300 165) strcat( (char *)&fmt[0], ": %s( %s" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 166) sprintf( (char *)&str[0], (const char *)&fmt[0], (char *)pexcept->name, (char *)&num[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 167) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 168) else
868b2b66 (kx 2024-12-20 16:11:07 +0300 169) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 170) strcpy( (char *)&fmt[0], exception );
868b2b66 (kx 2024-12-20 16:11:07 +0300 171) strcat( (char *)&fmt[0], ": %s( " );
868b2b66 (kx 2024-12-20 16:11:07 +0300 172) sprintf( (char *)&str[0], (const char *)&fmt[0], (char *)pexcept->name );
868b2b66 (kx 2024-12-20 16:11:07 +0300 173) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 174)
868b2b66 (kx 2024-12-20 16:11:07 +0300 175) if( pexcept->arg_2 )
868b2b66 (kx 2024-12-20 16:11:07 +0300 176) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 177) n_bits = pexcept->nb_a2 * BITS_PER_BYTE;
868b2b66 (kx 2024-12-20 16:11:07 +0300 178)
868b2b66 (kx 2024-12-20 16:11:07 +0300 179) unpack( (EMUSHORT *)&eic[0], (EMUSHORT *)pexcept->arg_2, n_bits );
868b2b66 (kx 2024-12-20 16:11:07 +0300 180)
868b2b66 (kx 2024-12-20 16:11:07 +0300 181) ei_real_to_ascii( (__mpu_char8_t *)&s[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 182) (EMUSHORT *)&eic[0],
868b2b66 (kx 2024-12-20 16:11:07 +0300 183) (_get_ndec( pexcept->nb_a2 ) < 12) ? _get_ndec( pexcept->nb_a2 ): 12,
868b2b66 (kx 2024-12-20 16:11:07 +0300 184) 'E', 0, 0, n_bits );
868b2b66 (kx 2024-12-20 16:11:07 +0300 185)
868b2b66 (kx 2024-12-20 16:11:07 +0300 186) strcpy( (char *)&num[0], (char *)&s[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 187) strcpy( (char *)&fmt[0], ", %s ): %s" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 188) sprintf( (char *)&st[0], (const char *)&fmt[0], (char *)&num[0], (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 189) strcat( (char *)&str[0], (char *)&st[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 190) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 191) else
868b2b66 (kx 2024-12-20 16:11:07 +0300 192) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 193) strcpy( (char *)&fmt[0], " ): %s" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 194) sprintf( (char *)&st[0], (const char *)&fmt[0], (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 195) strcat( (char *)&str[0], (char *)&st[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 196) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 197) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 198) break;
868b2b66 (kx 2024-12-20 16:11:07 +0300 199)
868b2b66 (kx 2024-12-20 16:11:07 +0300 200) default:
868b2b66 (kx 2024-12-20 16:11:07 +0300 201) {
868b2b66 (kx 2024-12-20 16:11:07 +0300 202) strcpy( (char *)&fmt[0], unknown );
868b2b66 (kx 2024-12-20 16:11:07 +0300 203) strcat( (char *)&fmt[0], ": %0.4d: %s(): %s" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 204) sprintf( (char *)&str[0], (const char *)&fmt[0], pexcept->type, (char *)pexcept->name, (char *)pexcept->msg );
868b2b66 (kx 2024-12-20 16:11:07 +0300 205) }
868b2b66 (kx 2024-12-20 16:11:07 +0300 206) break;
868b2b66 (kx 2024-12-20 16:11:07 +0300 207)
868b2b66 (kx 2024-12-20 16:11:07 +0300 208) } /* End switch( pexcept->who ) */
868b2b66 (kx 2024-12-20 16:11:07 +0300 209)
868b2b66 (kx 2024-12-20 16:11:07 +0300 210) strcpy( (char *)&fmt[0], "%s.\n" );
868b2b66 (kx 2024-12-20 16:11:07 +0300 211)
868b2b66 (kx 2024-12-20 16:11:07 +0300 212) fprintf( stderr, (const char *)&fmt[0], (char *)&str[0] );
868b2b66 (kx 2024-12-20 16:11:07 +0300 213)
868b2b66 (kx 2024-12-20 16:11:07 +0300 214) #if ENABLE_NLS == 1
868b2b66 (kx 2024-12-20 16:11:07 +0300 215) /* restore locale and environment */
868b2b66 (kx 2024-12-20 16:11:07 +0300 216) if( back_locale )
868b2b66 (kx 2024-12-20 16:11:07 +0300 217) (void)setlocale( LC_ALL, (const char *)back_locale );
868b2b66 (kx 2024-12-20 16:11:07 +0300 218)
868b2b66 (kx 2024-12-20 16:11:07 +0300 219) if( back_env )
868b2b66 (kx 2024-12-20 16:11:07 +0300 220) (void)setenv( (const char *)"LANGUAGE", (const char *)back_env, 1 /* 1 - overwrite */ );
868b2b66 (kx 2024-12-20 16:11:07 +0300 221) #endif
868b2b66 (kx 2024-12-20 16:11:07 +0300 222)
868b2b66 (kx 2024-12-20 16:11:07 +0300 223) return;
868b2b66 (kx 2024-12-20 16:11:07 +0300 224)
868b2b66 (kx 2024-12-20 16:11:07 +0300 225) } /* End of __mpu_warning() */