Merged
authorLaurent Bessard
Fri, 08 Mar 2013 01:01:15 +0100
changeset 799 214c9dced257
parent 798 d21e598b0b75 (current diff)
parent 715 134f110060db (diff)
child 800 2481fffe6e58
Merged
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){\