Обновление

This commit is contained in:
cfif 2025-12-18 14:23:30 +03:00
parent 446130290d
commit f36a5af4ab
1 changed files with 43 additions and 100 deletions

View File

@ -22,7 +22,7 @@ static int cvt_f(double number, int prec, int sharpflag, unsigned char *negp,
unsigned char fmtch, unsigned char *startp, unsigned char *endp); unsigned char fmtch, unsigned char *startp, unsigned char *endp);
#endif #endif
/*
int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap) { int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap) {
//#define PUTC(c) { putchar(stream,(unsigned char)(c)); ++retval; } //#define PUTC(c) { putchar(stream,(unsigned char)(c)); ++retval; }
#define PUTC(c) { char p = c; (logger)->logging((logger)->env, NULL, 0, 0, &p, 1, false); ++retval; } #define PUTC(c) { char p = c; (logger)->logging((logger)->env, NULL, 0, 0, &p, 1, false); ++retval; }
@ -222,7 +222,7 @@ int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap)
while (width--) while (width--)
PUTC (' '); PUTC (' ');
break; break;
#endif /* LY: AVR, and no break here! */ #endif // LY: AVR, and no break here!
case 's': case 's':
s = va_arg (ap, unsigned char*); s = va_arg (ap, unsigned char*);
@ -252,7 +252,7 @@ int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap)
break; break;
case 'r': case 'r':
/* Saturated counters. */ // Saturated counters.
base = 10; base = 10;
if (lflag) { if (lflag) {
ul = va_arg (ap, unsigned long); ul = va_arg (ap, unsigned long);
@ -374,10 +374,10 @@ int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap)
case 'g': case 'g':
case 'G': { case 'G': {
double d = va_arg (ap, double); double d = va_arg (ap, double);
/*
* don't do unrealistic precision; just pad it with // don't do unrealistic precision; just pad it with
* zeroes later, so buffer size stays rational. // zeroes later, so buffer size stays rational.
*/
if (dwidth > DBL_DIG) { if (dwidth > DBL_DIG) {
if ((c != 'g' && c != 'G') || sharpflag) if ((c != 'g' && c != 'G') || sharpflag)
extrazeros = dwidth - DBL_DIG; extrazeros = dwidth - DBL_DIG;
@ -385,19 +385,19 @@ int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap)
} else if (dwidth == -1) { } else if (dwidth == -1) {
dwidth = (lflag ? DBL_DIG : FLT_DIG); dwidth = (lflag ? DBL_DIG : FLT_DIG);
} }
/*
* softsign avoids negative 0 if d is < 0 and // softsign avoids negative 0 if d is < 0 and
* no significant digits will be shown // no significant digits will be shown
*/
if (d < 0) { if (d < 0) {
neg = 1; neg = 1;
d = -d; d = -d;
} }
/*
* cvt may have to round up past the "start" of the // cvt may have to round up past the "start" of the
* buffer, i.e. ``intf("%.2f", (double)9.999);''; // buffer, i.e. ``intf("%.2f", (double)9.999);'';
* if the first char isn't NULL, it did. // if the first char isn't NULL, it did.
*/
if (isnan (d) || isinf (d)) { if (isnan (d) || isinf (d)) {
strcpy(nbuf, isnan (d) ? "NaN" : "Inf"); strcpy(nbuf, isnan (d) ? "NaN" : "Inf");
size = 3; size = 3;
@ -458,12 +458,6 @@ int stream_logger_vprintf(tLoggerInterface *logger, char const *fmt, va_list ap)
} }
} }
/*
* Put a NUL-terminated ASCII number (base <= 16) in a buffer in reverse
* order; return an optional length and a pointer to the last character
* written in the buffer (i.e., the first character of the string).
* The buffer pointed to by `nbuf' must have length >= MAXNBUF.
*/
static unsigned char * static unsigned char *
ksprintn(unsigned char *nbuf, unsigned long ul, unsigned char base, int width, ksprintn(unsigned char *nbuf, unsigned long ul, unsigned char base, int width,
unsigned char *lenp) { unsigned char *lenp) {
@ -514,10 +508,10 @@ cvtround_f(double fract, int *exp, unsigned char *start, unsigned char *end, uns
} }
*end = '0'; *end = '0';
if (end == start) { if (end == start) {
if (exp) { /* e/E; increment exponent */ if (exp) { // e/E; increment exponent
*end = '1'; *end = '1';
++*exp; ++*exp;
} else { /* f; add extra digit */ } else { // f; add extra digit
*--end = '1'; *--end = '1';
--start; --start;
} }
@ -525,9 +519,8 @@ cvtround_f(double fract, int *exp, unsigned char *start, unsigned char *end, uns
} }
} }
} else if (*negp) { } else if (*negp) {
/* // ``"%.3f", (double)-0.0004'' gives you a negative 0.
* ``"%.3f", (double)-0.0004'' gives you a negative 0.
*/
for (;; --end) { for (;; --end) {
if (*end == '.') { if (*end == '.') {
--end; --end;
@ -581,39 +574,29 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
dotrim = expcnt = gformat = 0; dotrim = expcnt = gformat = 0;
fract = modf(number, &integer); fract = modf(number, &integer);
/*
* get an extra slot for rounding
*/
t = ++startp; t = ++startp;
/*
* get integer portion of number; put into the end of the buffer; the
* .01 is added for modf (356.0 / 10, &integer) returning .59999999...
*/
for (p = endp - 1; integer; ++expcnt) { for (p = endp - 1; integer; ++expcnt) {
tmp = modf(integer / 10, &integer); tmp = modf(integer / 10, &integer);
*p-- = (int) ((tmp + .01) * 10) + '0'; *p-- = (int) ((tmp + .01) * 10) + '0';
} }
switch (fmtch) { switch (fmtch) {
case 'f': case 'f':
/* reverse integer into beginning of buffer */
if (expcnt) { if (expcnt) {
for (; ++p < endp; *t++ = *p); for (; ++p < endp; *t++ = *p);
} else { } else {
*t++ = '0'; *t++ = '0';
} }
/*
* if precision required or alternate flag set, add in a
* decimal point.
*/
if (prec || sharpflag) { if (prec || sharpflag) {
*t++ = '.'; *t++ = '.';
} }
/*
* if requires more precision and some fraction left
*/
if (fract) { if (fract) {
if (prec) { if (prec) {
do { do {
@ -637,35 +620,23 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
*t++ = '.'; *t++ = '.';
} }
/*
* if requires more precision and some integer left
*/
for (; prec && ++p < endp; --prec) { for (; prec && ++p < endp; --prec) {
*t++ = *p; *t++ = *p;
} }
/*
* if done precision and more of the integer component,
* round using it; adjust fract so we don't re-round
* later.
*/
if (!prec && ++p < endp) { if (!prec && ++p < endp) {
fract = 0; fract = 0;
startp = cvtround_f(0, &expcnt, startp, startp = cvtround_f(0, &expcnt, startp,
t - 1, *p, negp); t - 1, *p, negp);
} }
/*
* adjust expcnt for digit in front of decimal
*/
--expcnt; --expcnt;
} }
/*
* until first fractional digit, decrement exponent
*/
else if (fract) { else if (fract) {
/*
* adjust expcnt for digit in front of decimal
*/
for (expcnt = -1;; --expcnt) { for (expcnt = -1;; --expcnt) {
fract = modf(fract * 10, &tmp); fract = modf(fract * 10, &tmp);
if (tmp) { if (tmp) {
@ -682,9 +653,7 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
*t++ = '.'; *t++ = '.';
} }
} }
/*
* if requires more precision and some fraction left
*/
if (fract) { if (fract) {
if (prec) { if (prec) {
do { do {
@ -697,14 +666,10 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
t - 1, '0', negp); t - 1, '0', negp);
} }
} }
/*
* if requires more precision
*/
for (; prec--; *t++ = '0'); for (; prec--; *t++ = '0');
/*
* unless alternate flag, trim any g/G format trailing 0's
*/
if (gformat && !sharpflag) { if (gformat && !sharpflag) {
while (t > startp && *--t == '0'); while (t > startp && *--t == '0');
if (*t == '.') { if (*t == '.') {
@ -716,54 +681,33 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
break; break;
case 'g': case 'g':
case 'G': case 'G':
/*
* a precision of 0 is treated as a precision of 1
*/
if (!prec) { if (!prec) {
++prec; ++prec;
} }
/*
* ``The style used depends on the value converted; style e
* will be used only if the exponent resulting from the
* conversion is less than -4 or greater than the precision.''
* -- ANSI X3J11
*/
if (expcnt > prec || (!expcnt && fract && fract < .0001)) { if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
/*
* g/G format counts "significant digits, not digits of
* precision; for the e/E format, this just causes an
* off-by-one problem, i.e. g/G considers the digit
* before the decimal point significant and e/E doesn't
* count it as precision.
*/
--prec; --prec;
fmtch -= 2; /* G->E, g->e */ fmtch -= 2;
gformat = 1; gformat = 1;
goto eformat; goto eformat;
} }
/*
* reverse integer into beginning of buffer,
* note, decrement precision
*/
if (expcnt) { if (expcnt) {
for (; ++p < endp; *t++ = *p, --prec); for (; ++p < endp; *t++ = *p, --prec);
} else { } else {
*t++ = '0'; *t++ = '0';
} }
/*
* if precision required or alternate flag set, add in a
* decimal point. If no digits yet, add in leading 0.
*/
if (prec || sharpflag) { if (prec || sharpflag) {
dotrim = 1; dotrim = 1;
*t++ = '.'; *t++ = '.';
} else { } else {
dotrim = 0; dotrim = 0;
} }
/*
* if requires more precision and some fraction left
*/
while (prec && fract) { while (prec && fract) {
fract = modf(fract * 10, &tmp); fract = modf(fract * 10, &tmp);
*t++ = (int) tmp + '0'; *t++ = (int) tmp + '0';
@ -772,9 +716,7 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
if (fract) { if (fract) {
startp = cvtround_f(fract, 0, startp, t - 1, '0', negp); startp = cvtround_f(fract, 0, startp, t - 1, '0', negp);
} }
/*
* alternate format, adds 0's for precision, else trim 0's
*/
if (sharpflag) { if (sharpflag) {
for (; prec--; *t++ = '0'); for (; prec--; *t++ = '0');
} else if (dotrim) { } else if (dotrim) {
@ -787,7 +729,8 @@ cvt_f(double number, int prec, int sharpflag, unsigned char *negp, unsigned char
return (t - startp); return (t - startp);
} }
#endif /* ARCH_HAVE_FPU */ #endif
*/
void LoggerPrintf( void LoggerPrintf(