add tests.
Catch the case (parsing and printing) of negative zero
unsigned int virtual : 1; //!< for dynamic expansion
- unsigned int is_signed : 1; //!< hackity hack for dates and time deltas
+ unsigned int is_unsigned : 1; //!< hackity hack for dates and time deltas
/*
* @todo - if we want to clean these fields up, make
case FR_TYPE_INT16:
if (type == FR_TYPE_DATE) goto unknown_type;
- flags->is_signed = true;
FALL_THROUGH;
case FR_TYPE_UINT16:
+ flags->is_unsigned = true;
flags->length = 2;
break;
case FR_TYPE_INT32:
if (type == FR_TYPE_DATE) goto unknown_type;
- flags->is_signed = true;
FALL_THROUGH;
case FR_TYPE_UINT32:
+ flags->is_unsigned = true;
flags->length = 4;
break;
case FR_TYPE_INT64:
if (type == FR_TYPE_DATE) goto unknown_type;
- flags->is_signed = true;
FALL_THROUGH;
case FR_TYPE_UINT64:
+ flags->is_unsigned = true;
flags->length = 8;
break;
}
uint64_t subsec = 0;
int scale = 1;
char *p, *end;
+ bool negative = false;
+
+ if (*in == '-') negative = true; /* catch the case of negative zero! */
sec = strtoll(in, &end, 10);
if (in == end) {
*/
if (*end) goto failed;
- *out = (minutes * 60 + sec) * NSEC;
+ if (negative) {
+ *out = (minutes * 60 - sec) * NSEC;
+ } else {
+ *out = (minutes * 60 + sec) * NSEC;
+ }
return 0;
} else if (*end) {
/*
* Now sec && subsec are in the same scale.
*/
- if (sec < 0) {
+ if (negative) {
if (sec <= (INT64_MIN / scale)) {
fr_strerror_const("Integer underflow in time_delta value.");
return -1;
if (!value->enumv) {
goto delta_size4;
- } else if (value->enumv->flags.is_signed) {
+ } else if (!value->enumv->flags.is_unsigned) {
switch (value->enumv->flags.length) {
case 2:
if (date < INT16_MIN) {
dst->enumv = enumv;
- if (!enumv || enumv->flags.is_signed) {
+ if (!enumv || !enumv->flags.is_unsigned) {
FR_DBUFF_OUT_INT64V_RETURN(&date, &work_dbuff, length);
} else {
uint64_t tmp;
break;
}
- if (!data->enumv || data->enumv->flags.is_signed) {
+ if (!data->enumv || !data->enumv->flags.is_unsigned) {
+ /*
+ * 0 is unsigned, but we want to print
+ * "-0.1" if necessary.
+ */
+ if ((lhs == 0) && (data->datum.time_delta < 0)) {
+ FR_SBUFF_IN_CHAR_RETURN(&our_out, '-');
+ }
+
FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "%" PRIi64 ".%09" PRIu64, lhs, rhs);
} else {
- if (lhs < 0) lhs = 0;
+ if (data->datum.time_delta < 0) {
+ lhs = rhs = 0;
+ }
FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "%" PRIu64 ".%09" PRIu64, lhs, rhs);
}
value time_delta 1:30
match 90
+value time_delta 1h
+match 3600
+
+#
+# And negative numbers
+#
+value time_delta -1
+match -1
+
+value time_delta -2.4
+match -2.4
+
+value time_delta -0.001
+match -0.001
+
+value time_delta -1ms
+match -0.001
+
+value time_delta -1us
+match -0.000001
+
+value time_delta -1.5us
+match -0.0000015
+
+value time_delta -1ns
+match -0.000000001
+
+value time_delta -1:30
+match -90
+
+value time_delta -1h
+match -3600
+
+
+
+#
+# uint8
+#
value uint8 256
match Value 256 is invalid for type uint8 (must be in range 0...255)
count
-match 78
+match 98