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