Skip to content

Commit b60bc79

Browse files
authored
1 parent 0af4944 commit b60bc79

File tree

1 file changed

+51
-48
lines changed

1 file changed

+51
-48
lines changed

Modelica/Resources/C-Sources/snprintf.c

+51-48
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
* HAVE_STDDEF_H
114114
* HAVE_STDINT_H
115115
* HAVE_STDLIB_H
116+
* HAVE_FLOAT_H
116117
* HAVE_INTTYPES_H
117118
* HAVE_LOCALE_H
118119
* HAVE_LOCALECONV
@@ -169,6 +170,9 @@
169170
#ifndef HAVE_STDLIB_H
170171
#define HAVE_STDLIB_H 1
171172
#endif
173+
#ifndef HAVE_FLOAT_H
174+
#define HAVE_FLOAT_H 1
175+
#endif
172176

173177
/* Define to 1 if you have a C99 compliant `snprintf' function. */
174178
#if defined(STDC99)
@@ -313,13 +317,16 @@
313317
#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list))
314318
#define VA_END_COPY(ap) /* No-op. */
315319
#define NEED_MYMEMCPY 1
316-
static void *mymemcpy(void *, void *, size_t);
320+
static void *mymemcpy(void *, const void *, size_t);
317321
#endif /* HAVE_VA_COPY */
318322
#endif /* !HAVE_VASPRINTF */
319323

320324
#if !HAVE_VSNPRINTF
321325
#include <errno.h> /* For ERANGE and errno. */
322326
#include <limits.h> /* For *_MAX. */
327+
#if HAVE_FLOAT_H
328+
#include <float.h> /* For *DBL_{MIN,MAX}_10_EXP. */
329+
#endif /* HAVE_FLOAT_H */
323330
#if HAVE_INTTYPES_H
324331
#include <inttypes.h> /* For intmax_t (if not defined in <stdint.h>). */
325332
#endif /* HAVE_INTTYPES_H */
@@ -378,8 +385,12 @@ static void *mymemcpy(void *, void *, size_t);
378385
#ifndef LDOUBLE
379386
#if HAVE_LONG_DOUBLE
380387
#define LDOUBLE long double
388+
#define LDOUBLE_MIN_10_EXP LDBL_MIN_10_EXP
389+
#define LDOUBLE_MAX_10_EXP LDBL_MAX_10_EXP
381390
#else
382391
#define LDOUBLE double
392+
#define LDOUBLE_MIN_10_EXP DBL_MIN_10_EXP
393+
#define LDOUBLE_MAX_10_EXP DBL_MAX_10_EXP
383394
#endif /* HAVE_LONG_DOUBLE */
384395
#endif /* !defined(LDOUBLE) */
385396

@@ -498,7 +509,7 @@ static void *mymemcpy(void *, void *, size_t);
498509
#define ISNAN(x) (x != x)
499510
#endif /* !defined(ISNAN) */
500511
#ifndef ISINF
501-
#define ISINF(x) (x != 0.0 && x + x == x)
512+
#define ISINF(x) ((x < -1 || x > 1) && x + x == x)
502513
#endif /* !defined(ISINF) */
503514

504515
#ifdef OUTCHAR
@@ -774,50 +785,33 @@ rpl_vsnprintf(char *str, size_t size, const char *format, va_list args)
774785
case 'A':
775786
/* Not yet supported, we'll use "%F". */
776787
/* FALLTHROUGH */
788+
case 'E':
789+
if (ch == 'E')
790+
flags |= PRINT_F_TYPE_E;
791+
/* FALLTHROUGH */
792+
case 'G':
793+
if (ch == 'G')
794+
flags |= PRINT_F_TYPE_G;
795+
/* FALLTHROUGH */
777796
case 'F':
778797
flags |= PRINT_F_UP;
798+
/* FALLTHROUGH */
779799
case 'a':
780800
/* Not yet supported, we'll use "%f". */
781801
/* FALLTHROUGH */
782-
case 'f':
783-
if (cflags == PRINT_C_LDOUBLE)
784-
fvalue = va_arg(args, LDOUBLE);
785-
else
786-
fvalue = va_arg(args, double);
787-
fmtflt(str, &len, size, fvalue, width,
788-
precision, flags, &overflow);
789-
if (overflow)
790-
goto out;
791-
break;
792-
case 'E':
793-
flags |= PRINT_F_UP;
794-
/* FALLTHROUGH */
795802
case 'e':
796-
flags |= PRINT_F_TYPE_E;
797-
if (cflags == PRINT_C_LDOUBLE)
798-
fvalue = va_arg(args, LDOUBLE);
799-
else
800-
fvalue = va_arg(args, double);
801-
fmtflt(str, &len, size, fvalue, width,
802-
precision, flags, &overflow);
803-
if (overflow)
804-
goto out;
805-
break;
806-
case 'G':
807-
flags |= PRINT_F_UP;
803+
if (ch == 'e')
804+
flags |= PRINT_F_TYPE_E;
808805
/* FALLTHROUGH */
809806
case 'g':
810-
flags |= PRINT_F_TYPE_G;
807+
if (ch == 'g')
808+
flags |= PRINT_F_TYPE_G;
809+
/* FALLTHROUGH */
810+
case 'f':
811811
if (cflags == PRINT_C_LDOUBLE)
812812
fvalue = va_arg(args, LDOUBLE);
813813
else
814814
fvalue = va_arg(args, double);
815-
/*
816-
* If the precision is zero, it is treated as
817-
* one (cf. C99: 7.19.6.1, 8).
818-
*/
819-
if (precision == 0)
820-
precision = 1;
821815
fmtflt(str, &len, size, fvalue, width,
822816
precision, flags, &overflow);
823817
if (overflow)
@@ -951,7 +945,7 @@ fmtstr(char *str, size_t *len, size_t size, const char *value, int width,
951945
OUTCHAR(str, *len, size, ' ');
952946
padlen--;
953947
}
954-
while (*value != '\0' && (noprecision || precision-- > 0)) {
948+
while ((noprecision || precision-- > 0) && *value != '\0') {
955949
OUTCHAR(str, *len, size, *value);
956950
value++;
957951
}
@@ -1073,7 +1067,7 @@ fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
10731067
const char *infnan = NULL;
10741068
char iconvert[MAX_CONVERT_LENGTH];
10751069
char fconvert[MAX_CONVERT_LENGTH];
1076-
char econvert[4]; /* "e-12" (without nul-termination). */
1070+
char econvert[5]; /* "e-300" (without nul-termination). */
10771071
char esign = 0;
10781072
char sign = 0;
10791073
int leadfraczeros = 0;
@@ -1123,6 +1117,12 @@ fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
11231117
/* "%e" (or "%E") or "%g" (or "%G") conversion. */
11241118
if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) {
11251119
if (flags & PRINT_F_TYPE_G) {
1120+
/*
1121+
* If the precision is zero, it is treated as one (cf.
1122+
* C99: 7.19.6.1, 8).
1123+
*/
1124+
if (precision == 0)
1125+
precision = 1;
11261126
/*
11271127
* For "%g" (and "%G") conversions, the precision
11281128
* specifies the number of significant digits, which
@@ -1242,12 +1242,12 @@ fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
12421242
esign = '+';
12431243

12441244
/*
1245-
* Convert the exponent. The sizeof(econvert) is 4. So, the
1246-
* econvert buffer can hold e.g. "e+99" and "e-99". We don't
1247-
* support an exponent which contains more than two digits.
1245+
* Convert the exponent. The sizeof(econvert) is 5. So, the
1246+
* econvert buffer can hold e.g. "e+999" and "e-999". We don't
1247+
* support an exponent which contains more than three digits.
12481248
* Therefore, the following stores are safe.
12491249
*/
1250-
epos = convert(exponent, econvert, 2, 10, 0);
1250+
epos = convert(exponent, econvert, 3, 10, 0);
12511251
/*
12521252
* C99 says: "The exponent always contains at least two digits,
12531253
* and only as many more digits as necessary to represent the
@@ -1391,15 +1391,15 @@ getexponent(LDOUBLE value)
13911391
int exponent = 0;
13921392

13931393
/*
1394-
* We check for 99 > exponent > -99 in order to work around possible
1395-
* endless loops which could happen (at least) in the second loop (at
1396-
* least) if we're called with an infinite value. However, we checked
1397-
* for infinity before calling this function using our ISINF() macro, so
1398-
* this might be somewhat paranoid.
1394+
* We check for LDOUBLE_MAX_10_EXP >= exponent >= LDOUBLE_MIN_10_EXP in
1395+
* order to work around possible endless loops which could happen (at
1396+
* least) in the second loop (at least) if we're called with an infinite
1397+
* value. However, we checked for infinity before calling this function
1398+
* using our ISINF() macro, so this might be somewhat paranoid.
13991399
*/
1400-
while (tmp < 1.0 && tmp > 0.0 && --exponent > -99)
1400+
while (tmp < 1.0 && tmp > 0.0 && --exponent >= LDOUBLE_MIN_10_EXP)
14011401
tmp *= 10;
1402-
while (tmp >= 10.0 && ++exponent < 99)
1402+
while (tmp >= 10.0 && ++exponent <= LDOUBLE_MAX_10_EXP)
14031403
tmp /= 10;
14041404

14051405
return exponent;
@@ -1449,6 +1449,9 @@ myround(LDOUBLE value)
14491449
{
14501450
UINTMAX_T intpart = cast(value);
14511451

1452+
if (intpart == UINTMAX_MAX)
1453+
return UINTMAX_MAX;
1454+
14521455
return ((value -= intpart) < 0.5) ? intpart : intpart + 1;
14531456
}
14541457

@@ -1472,7 +1475,7 @@ mypow10(int exponent)
14721475
#if !HAVE_VASPRINTF
14731476
#if NEED_MYMEMCPY
14741477
static void *
1475-
mymemcpy(void *dst, void *src, size_t len)
1478+
mymemcpy(void *dst, const void *src, size_t len)
14761479
{
14771480
const char *from = (const char *)src;
14781481
char *to = (char*)dst;

0 commit comments

Comments
 (0)