remove undefined behaviour of right shifting a negative value - jfconvert - JSON Feed (subset) to sfeed or Atom converter
(HTM) git clone git://git.codemadness.org/jfconvert
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit d120a3f0e83fd23ba1da44b44fddbbe73a959fc3
(DIR) parent 652087ec6b963ac8e2135f1faca93f0a2f31c0d7
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Fri, 12 Dec 2025 01:06:34 +0100
remove undefined behaviour of right shifting a negative value
This rewrites the bitshift hack in a more clear and defined behaviour.
synced from sfeed
Diffstat:
M jf2sfeed.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
---
(DIR) diff --git a/jf2sfeed.c b/jf2sfeed.c
@@ -94,8 +94,8 @@ errx(int exitstatus, const char *fmt, ...)
}
/* Convert time fields. Returns a signed (at least) 64-bit UNIX timestamp.
- Parameters should be passed as they are in a struct tm:
- that is: year = year - 1900, month = month - 1. */
+ * Parameters should be passed as they are in a struct tm and in a valid range:
+ * that is: year = year - 1900, month = month - 1. */
static long long
datetounix(long long year, int mon, int day, int hour, int min, int sec)
{
@@ -110,8 +110,8 @@ datetounix(long long year, int mon, int day, int hour, int min, int sec)
/* optimization: handle common range year 1902 up to and including 2038 */
if (year - 2ULL <= 136) {
/* amount of leap days relative to 1970: every 4 years */
- leaps = (year - 68) >> 2;
- if (!((year - 68) & 3)) {
+ leaps = (year / 4) - 17; /* 17 leap years offset for 1902 - 1970 */
+ if (!(year & 3)) {
leaps--;
is_leap = 1;
} else {
@@ -120,8 +120,8 @@ datetounix(long long year, int mon, int day, int hour, int min, int sec)
t = 31536000 * (year - 70) + (86400 * leaps); /* 365 * 86400 = 31536000 */
} else {
/* general leap year calculation:
- leap years occur mostly every 4 years but every 100 years
- a leap year is skipped unless the year is divisible by 400 */
+ * leap years occur mostly every 4 years but every 100 years
+ * a leap year is skipped unless the year is divisible by 400 */
cycles = (year - 100) / 400;
rem = (year - 100) % 400;
if (rem < 0) {
@@ -150,7 +150,7 @@ datetounix(long long year, int mon, int day, int hour, int min, int sec)
leaps += (97 * cycles) + (24 * centuries) - is_leap;
/* adjust 8 leap days from 1970 up to and including 2000:
- ((30 * 365) + 8) * 86400 = 946771200 */
+ * ((30 * 365) + 8) * 86400 = 946771200 */
t = ((year - 100) * 31536000LL) + (leaps * 86400LL) + 946771200LL;
}
t += secs_through_month[mon];