+---
+* [Bug 3491] Signed values of LFP datatypes should always display a sign
+ - applied patch by Gerry Garvey & fixed unit tests <perlinger@ntp.org>
+
---
(4.2.8p13) 2019/03/07 Released by Harlan Stenn <stenn@ntp.org>
/*
* Prototypes
*/
-extern char * dofptoa (u_fp, int, short, int);
-extern char * dolfptoa (u_int32, u_int32, int, short, int);
+extern char * dofptoa (u_fp, char, short, int);
+extern char * dolfptoa (u_int32, u_int32, char, short, int);
extern int atolfp (const char *, l_fp *);
extern int buftvtots (const char *, l_fp *);
char *
dofptoa(
u_fp fpv,
- int neg,
+ char sign,
short ndec,
int msec
)
* Copy it into the buffer, asciizing as we go.
*/
bp = buf;
- if (neg)
- *bp++ = '-';
+ if (sign)
+ *bp++ = sign;
while (cp < cpend) {
if (cp == cpdec)
plusfp = (u_fp)fpv;
}
- return dofptoa(plusfp, neg, ndec, FALSE);
+ return dofptoa(plusfp, (neg?'-':0), ndec, FALSE);
}
plusfp = (u_fp)fpv;
}
- return dofptoa(plusfp, neg, ndec, TRUE);
+ return dofptoa(plusfp, (neg?'-':0), ndec, TRUE);
}
dolfptoa(
u_int32 fpi,
u_int32 fpv,
- int neg,
+ char sign,
short ndec,
int msec
)
cp = cpdec - 1;
bp = buf;
- if (neg)
- *bp++ = '-';
+ if (sign)
+ *bp++ = sign;
while (cp < cpend) {
if (cp == cpdec)
*bp++ = '.';
M_NEG(fpi, fpf);
}
- return dolfptoa(fpi, fpf, isneg, ndec, FALSE);
+ return dolfptoa(fpi, fpf, (isneg?'-':'+'), ndec, FALSE);
}
M_NEG(fpi, fpf);
}
- return dolfptoa(fpi, fpf, isneg, ndec, TRUE);
+ return dolfptoa(fpi, fpf, (isneg?'-':'+'), ndec, TRUE);
}
/*
* We understand numbers of the form:
*
- * [spaces][-][digits][.][digits][spaces|\n|\0]
+ * [spaces][-|+][digits][.][digits][spaces|\n|\0]
*
* This is one enormous hack. Since I didn't feel like
* rewriting the decoding routine for milliseconds, what
while (isspace((unsigned char)*cp))
cp++;
- if (*cp == '-') {
- *bp++ = '-';
- cp++;
+ if (*cp == '-' || *cp == '+') {
+ *bp++ = *cp++;
}
if (*cp != '.' && !isdigit((unsigned char)*cp))
when(&ts, &rec, &reftime)),
prettyinterval(pollbuf, sizeof(pollbuf),
(int)poll_sec),
- reach, lfptoms(&estdelay, 3),
+ reach, ulfptoms(&estdelay, 3),
lfptoms(&estoffset, 3),
(have_jitter)
- ? lfptoms(&estjitter, 3)
- : lfptoms(&estdisp, 3));
+ ? ulfptoms(&estjitter, 3)
+ : ulfptoms(&estdisp, 3));
return (1);
}
else
#define NA 2 /* network address */
#define LP 3 /* leap (print in binary) */
#define RF 4 /* refid (sometimes string, sometimes not) */
-#define AR 5 /* array of times */
+#define AU 5 /* array of unsigned times */
#define FX 6 /* test flags */
#define TS 7 /* l_fp timestamp in hex */
#define OC 8 /* integer, print in octal */
+#define AS 9 /* array of signed times */
+#define SN 10 /* signed number: must display +/- sign */
#define EOV 255 /* end of table */
/*
{ "srcadr", HA },
{ "peeradr", HA }, /* compat with others */
{ "dstadr", NA },
- { "filtdelay", AR },
- { "filtoffset", AR },
- { "filtdisp", AR },
- { "filterror", AR }, /* compat with others */
+ { "filtdelay", AU },
+ { "filtoffset", AS },
+ { "filtdisp", AU },
+ { "filterror", AU }, /* compat with others */
+ { "offset", SN },
+ { "frequency", SN }
};
static void startoutput (void);
static void output (FILE *, const char *, const char *);
static void endoutput (FILE *);
-static void outputarr (FILE *, char *, int, l_fp *);
+static void outputarr (FILE *, char *, int, l_fp *, int);
static int assoccmp (const void *, const void *);
u_short varfmt (const char *);
void ntpq_custom_opt_handler(tOptions *, tOptDesc *);
FILE *fp,
char *name,
int narr,
- l_fp *lfp
+ l_fp *lfp,
+ int issigned
)
{
char *bp;
for (i = narr; i > 0; i--) {
if (i != (size_t)narr)
*bp++ = ' ';
- cp = lfptoms(lfp, 2);
+ cp = (issigned ? lfptoms(lfp, 2) : ulfptoms(lfp, 2));
len = strlen(cp);
if (len > 7) {
cp[7] = '\0';
}
break;
- case AR:
+ case AU:
+ case AS:
if (!value || !decodearr(value, &narr, lfparr, 8))
output_raw = '?';
else
- outputarr(fp, name, narr, lfparr);
+ outputarr(fp, name, narr, lfparr, (fmt==AS));
break;
case FX:
output(fp, name, tstflags(uval));
break;
+ case SN:
+ if (!value)
+ output_raw = '?';
+ else if (isdigit(*value)) { /* number without sign */
+ bv[0] = '+';
+ atoascii (value, MAXVALLEN, bv+1, sizeof(bv)-1);
+ output(fp, name, bv);
+ } else
+ output_raw = '*'; /* output as-is */
+ break;
+
default:
fprintf(stderr, "Internal error in cookedprint, %s=%s, fmt %d\n",
name, value, fmt);
test_PositiveInteger(void) {
l_fp test = {{200}, 0}; /* exact 200.0000000000 */
- TEST_ASSERT_EQUAL_STRING("200.0000000000", mfptoa(test.l_ui, test.l_uf, LFP_MAX_PRECISION));
- TEST_ASSERT_EQUAL_STRING("200000.0000000", mfptoms(test.l_ui, test.l_uf, LFP_MAX_PRECISION_MS));
+ TEST_ASSERT_EQUAL_STRING("+200.0000000000", mfptoa(test.l_ui, test.l_uf, LFP_MAX_PRECISION));
+ TEST_ASSERT_EQUAL_STRING("+200000.0000000", mfptoms(test.l_ui, test.l_uf, LFP_MAX_PRECISION_MS));
}
void
test_PositiveIntegerWithFraction(void) {
l_fp test = {{200}, ONE_FOURTH}; /* 200.25 */
- TEST_ASSERT_EQUAL_STRING("200.2500000000", lfptoa(&test, LFP_MAX_PRECISION));
- TEST_ASSERT_EQUAL_STRING("200250.0000000", lfptoms(&test, LFP_MAX_PRECISION_MS));
+ TEST_ASSERT_EQUAL_STRING("+200.2500000000", lfptoa(&test, LFP_MAX_PRECISION));
+ TEST_ASSERT_EQUAL_STRING("+200250.0000000", lfptoms(&test, LFP_MAX_PRECISION_MS));
}
void
test_RoundingDownToInteger(void) {
l_fp test = {{10}, ONE_FOURTH}; /* 10.25 */
- TEST_ASSERT_EQUAL_STRING("10", lfptoa(&test, 0));
- TEST_ASSERT_EQUAL_STRING("10250", lfptoms(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+10", lfptoa(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+10250", lfptoms(&test, 0));
}
void
test_RoundingMiddleToInteger(void) {
l_fp test = {{10}, HALF}; /* 10.5 */
- TEST_ASSERT_EQUAL_STRING("11", lfptoa(&test, 0));
- TEST_ASSERT_EQUAL_STRING("10500", lfptoms(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+11", lfptoa(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+10500", lfptoms(&test, 0));
}
void
test_RoundingUpToInteger(void) {
l_fp test = {{5}, THREE_FOURTH}; /* 5.75 */
- TEST_ASSERT_EQUAL_STRING("6", lfptoa(&test, 0));
- TEST_ASSERT_EQUAL_STRING("5750", lfptoms(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+6", lfptoa(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+5750", lfptoms(&test, 0));
}
void
test_SingleDecimal(void) {
l_fp test = {{8}, ONE_FOURTH}; /* 8.25 */
- TEST_ASSERT_EQUAL_STRING("8.3", lfptoa(&test, 1));
- TEST_ASSERT_EQUAL_STRING("8250.0", lfptoms(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+8.3", lfptoa(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+8250.0", lfptoms(&test, 1));
}
void
test_MillisecondsRoundingUp(void) {
l_fp test = {{1}, HALF_PROMILLE_UP}; /* slightly more than 1.0005 */
- TEST_ASSERT_EQUAL_STRING("1.0", lfptoa(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+1.0", lfptoa(&test, 1));
- TEST_ASSERT_EQUAL_STRING("1000.5", lfptoms(&test, 1));
- TEST_ASSERT_EQUAL_STRING("1001", lfptoms(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+1000.5", lfptoms(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+1001", lfptoms(&test, 0));
}
void
test_MillisecondsRoundingDown(void) {
l_fp test = {{1}, HALF_PROMILLE_DOWN}; /* slightly less than 1.0005 */
- TEST_ASSERT_EQUAL_STRING("1.0", lfptoa(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+1.0", lfptoa(&test, 1));
- TEST_ASSERT_EQUAL_STRING("1000.5", lfptoms(&test, 1));
- TEST_ASSERT_EQUAL_STRING("1000", lfptoms(&test, 0));
+ TEST_ASSERT_EQUAL_STRING("+1000.5", lfptoms(&test, 1));
+ TEST_ASSERT_EQUAL_STRING("+1000", lfptoms(&test, 0));
}
void test_UnsignedInteger(void) {
rtol(0xfefffffe, "-0.00000048");
rtol(0xfeffffff, "-0.00000024");
- rtol(0xfe000000, "0.00000000");
- rtol(0xfe000001, "0.00000024");
- rtol(0xfe6ffffe, "1.74999952");
- rtol(0xfe6fffff, "1.74999976");
- rtol(0xfe700000, "1.75000000");
- rtol(0xfe700001, "1.75000024");
- rtol(0xfe7ffffe, "1.99999952");
- rtol(0xfe7fffff, "1.99999976");
+ rtol(0xfe000000, "+0.00000000");
+ rtol(0xfe000001, "+0.00000024");
+ rtol(0xfe6ffffe, "+1.74999952");
+ rtol(0xfe6fffff, "+1.74999976");
+ rtol(0xfe700000, "+1.75000000");
+ rtol(0xfe700001, "+1.75000024");
+ rtol(0xfe7ffffe, "+1.99999952");
+ rtol(0xfe7fffff, "+1.99999976");
rtoltor(0xfe800000, "-2.00000000");
rtoltor(0xfe800001, "-1.99999976");
rtoltor(0xfefffffe, "-0.00000048");
rtoltor(0xfeffffff, "-0.00000024");
- rtoltor(0xfe000000, "0.00000000");
- rtoltor(0xfe000001, "0.00000024");
- rtoltor(0xfe6ffffe, "1.74999952");
- rtoltor(0xfe6fffff, "1.74999976");
- rtoltor(0xfe700000, "1.75000000");
- rtoltor(0xfe700001, "1.75000024");
- rtoltor(0xfe7ffffe, "1.99999952");
- rtoltor(0xfe7fffff, "1.99999976");
+ rtoltor(0xfe000000, "+0.00000000");
+ rtoltor(0xfe000001, "+0.00000024");
+ rtoltor(0xfe6ffffe, "+1.74999952");
+ rtoltor(0xfe6fffff, "+1.74999976");
+ rtoltor(0xfe700000, "+1.75000000");
+ rtoltor(0xfe700001, "+1.75000024");
+ rtoltor(0xfe7ffffe, "+1.99999952");
+ rtoltor(0xfe7fffff, "+1.99999976");
return;
}