/*************************************************************** __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 #endif #include #include /* errno(3) */ #include /* strcpy(3) */ #include /* bzero(3) */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* __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() */