# HG changeset patch # User Laurent Bessard # Date 1361657699 -3600 # Node ID 134f110060dbaa7847b8404f531a430db0c143ff # Parent 91fe9690080099f1f6f572be5d5a4f0ab74aa74d Added support for testing BCD value validity in BCD_TO_UINT function diff -r 91fe96900800 -r 134f110060db lib/iec_std_lib.h --- a/lib/iec_std_lib.h Sat Feb 23 22:38:37 2013 +0100 +++ b/lib/iec_std_lib.h Sat Feb 23 23:14:59 2013 +0100 @@ -652,29 +652,33 @@ /*****************/ /* 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; } @@ -982,7 +986,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){\