# HG changeset patch # User Laurent Bessard # Date 1362700875 -3600 # Node ID 214c9dced2578b93d2216d3ddf7cab36012a1fba # Parent d21e598b0b75c7dbd74cc30d4d1e4270d770c03c# Parent 134f110060dbaa7847b8404f531a430db0c143ff Merged diff -r d21e598b0b75 -r 214c9dced257 lib/iec_std_lib.h --- a/lib/iec_std_lib.h Sun Jan 13 16:06:00 2013 +0000 +++ b/lib/iec_std_lib.h Fri Mar 08 01:01:15 2013 +0100 @@ -228,7 +228,8 @@ } #define EPOCH_YEAR 1970 -#define SECONDS_PER_HOUR (60 * 60) +#define SECONDS_PER_MINUTE 60 +#define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE) #define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR) #define __isleap(year) \ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) @@ -549,15 +550,15 @@ div_t days; /*t#5d14h12m18s3.5ms*/ res = __INIT_STRING; - days = div(IN.tv_sec ,86400); + days = div(IN.tv_sec, SECONDS_PER_DAY); if(!days.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd", days.quot); }else{ - div_t hours = div(days.rem, 3600); + div_t hours = div(days.rem, SECONDS_PER_HOUR); if(!hours.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh", days.quot, hours.quot); }else{ - div_t minuts = div(hours.rem, 60); + div_t minuts = div(hours.rem, SECONDS_PER_MINUTE); if(!minuts.rem && IN.tv_nsec == 0){ res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm", days.quot, hours.quot, minuts.quot); }else{ @@ -641,35 +642,47 @@ /* [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME] */ /**********************************************/ -static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % (24*60*60), IN.tv_nsec};} -static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};} +static inline TOD __date_and_time_to_time_of_day(DT IN) { + return (TOD){ + IN.tv_sec % SECONDS_PER_DAY + (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0), + IN.tv_nsec}; +} +static inline DATE __date_and_time_to_date(DT IN){ + return (DATE){ + IN.tv_sec - IN.tv_sec % SECONDS_PER_DAY - (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0), + 0}; +} /*****************/ /* FROM/TO BCD */ /*****************/ -#define __bcd_digit(fac) + +static inline BOOL __test_bcd(LWORD IN) { + while (IN) { + if ((IN & 0xf) > 9) return 1; + IN >>= 4; + } + return 0; +} + static inline ULINT __bcd_to_uint(LWORD IN){ - ULINT res; - ULINT i; - - res = IN & 0xf; - for(i = 10ULL; i <= 1000000000000000ULL; i *= 10){ - if(!(IN >>= 4)) - break; - res += (IN & 0xf) * i; + ULINT res = IN & 0xf; + ULINT factor = 10ULL; + + while (IN >>= 4) { + res += (IN & 0xf) * factor; + factor *= 10; } return res; } static inline LWORD __uint_to_bcd(ULINT IN){ - LWORD res; - USINT i; - - res = IN % 10; - for(i = 4; i<=60; i += 4){ - if(!(IN /= 10)) - break; - res |= (IN % 10) << i; + LWORD res = IN % 10; + USINT shift = 4; + + while (IN /= 10) { + res |= (IN % 10) << shift; + shift += 4; } return res; } @@ -977,7 +990,7 @@ /******** BCD_TO_ ************/ #define __iec_(to_TYPENAME,from_TYPENAME) \ static inline to_TYPENAME from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\ - TEST_EN(to_TYPENAME)\ + TEST_EN_COND(to_TYPENAME, __test_bcd(op))\ return (to_TYPENAME)__bcd_to_uint(op);\ }\ static inline to_TYPENAME BCD_TO_##to_TYPENAME##__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\