/***************************************************************
__MPU_STRERROR.C
This file contains source code of functions for
getting MATH ERROR messages.
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>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <libmpu.h>
#include <mpu-context.h>
#include <mpu-symbols.h>
#include <mpu-math-errno.h>
#include <mpu-mtherr.h>
#include <mpu-real.h>
#define MPU_MATH_EUNKNOWN_MSG "Unknown MPU error"
/***************************************************************
__mpu_utf8mpu_error()
Возврашает указатель на строку, содержащую текстовый
эквивалент ошибок MPU( Math Processor Unit ), имеющих
код ERRNUM.
Параметр WHO определяет источник ошибки и может иметь
одно из, определенных в __tx_math_errno.h, значений:
#define _COMPLEX_ 3
#define _REAL_ 2
#define _INTEGER_ 1
#define _MATH_ 0
.
Возвращаемое значение переводится в кодировку UTF-8,
согласно локали ru.
В случае ошибки возвращает RET == (__mpu_utf8_t *)NULL.
NOTE:
====
Функция выделяет память под возвращаемый указатель.
Ответственность за освобождение данной памяти лежит
на ползователе.
***************************************************************/
__mpu_utf8_t *
__mpu_utf8mpu_error( int who, __mpu_error_t errnum )
{
__mpu_utf8_t *e = NULL;
__mpu_utf8_t *ret = NULL;
switch( who )
{
case _COMPLEX_:
e = (__mpu_utf8_t *)__MPU_COMPLEX_ERR_MSG( errnum );
break;
case _REAL_ :
e = (__mpu_utf8_t *)__MPU_REAL_ERR_MSG( errnum );
break;
case _INTEGER_:
e = (__mpu_utf8_t *)__MPU_INTEGER_ERR_MSG( errnum );
break;
case _MATH_ :
e = (__mpu_utf8_t *)__MPU_MATH_ERR_MSG( errnum );
break;
}
if( e == (__mpu_utf8_t *)0 )
{
/****************************************************
NOTE:
MPU_MATH_ERROR_MSG_SIZE определено в
LIBMPU.H ( == 4096).
****************************************************/
static __mpu_utf8_t unknow_error[MPU_MATH_ERROR_MSG_SIZE];
static __mpu_utf8_t code_error[64];
strncpy( unknow_error, (__mpu_utf8_t *)MPU_MATH_EUNKNOWN_MSG, (size_t)(MPU_MATH_ERROR_MSG_SIZE-1) );
unknow_error[MPU_MATH_ERROR_MSG_SIZE-1] = '\0';
snprintf( code_error, (size_t)64, ": #%d", errnum );
strncat( unknow_error, code_error, (size_t)(MPU_MATH_ERROR_MSG_SIZE-1) );
unknow_error[MPU_MATH_ERROR_MSG_SIZE-1] = '\0';
e = unknow_error;
}
/* а вот теперь можно применить gettext: */
/* ==================================== */
{
#if ENABLE_NLS == 1
char *back_locale = NULL;
char *lt = NULL;
char *back_env = NULL;
#endif
size_t len = 0;
#if ENABLE_NLS == 1
/*******************************************************
Так как 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 */ );
e = (__mpu_utf8_t *)dgettext( PACKAGE, (const char *)e );
#endif
len = strlen( e );
ret = (__mpu_utf8_t *)malloc( (len + 1) * sizeof( __mpu_utf8_t ) );
if( !ret )
{
#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( (__mpu_utf8_t *)NULL );
}
strncpy( ret, e, len+1 );
#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( ret );
} /* End of __mpu_utf8mpu_error() */