lib/iec_std_lib.h
changeset 849 1f8885ae539a
parent 818 2a3f34967cae
child 900 1e749c7b70f8
equal deleted inserted replaced
823:c95f42f28b69 849:1f8885ae539a
   109 #define __WORD_LITERAL(value) __literal(WORD,value)
   109 #define __WORD_LITERAL(value) __literal(WORD,value)
   110 #define __DWORD_LITERAL(value) __literal(DWORD,value,__32b_sufix)
   110 #define __DWORD_LITERAL(value) __literal(DWORD,value,__32b_sufix)
   111 #define __LWORD_LITERAL(value) __literal(LWORD,value,__64b_sufix)
   111 #define __LWORD_LITERAL(value) __literal(LWORD,value,__64b_sufix)
   112 
   112 
   113 
   113 
   114 
       
   115 #define __INIT_REAL 0
       
   116 #define __INIT_LREAL 0
       
   117 #define __INIT_SINT 0
       
   118 #define __INIT_INT 0
       
   119 #define __INIT_DINT 0
       
   120 #define __INIT_LINT 0
       
   121 #define __INIT_USINT 0
       
   122 #define __INIT_UINT 0
       
   123 #define __INIT_UDINT 0
       
   124 #define __INIT_ULINT 0
       
   125 #define __INIT_TIME (TIME){0,0}
       
   126 #define __INIT_BOOL 0
       
   127 #define __INIT_BYTE 0
       
   128 #define __INIT_WORD 0
       
   129 #define __INIT_DWORD 0
       
   130 #define __INIT_LWORD 0
       
   131 #define __INIT_STRING (STRING){0,""}
       
   132 //#define __INIT_WSTRING
       
   133 #define __INIT_DATE (DATE){0,0}
       
   134 #define __INIT_TOD (TOD){0,0}
       
   135 #define __INIT_DT (DT){0,0}
       
   136 
       
   137 typedef union __IL_DEFVAR_T {
   114 typedef union __IL_DEFVAR_T {
   138     BOOL    BOOLvar;
   115     BOOL    BOOLvar;
   139 
   116 
   140     SINT    SINTvar;
   117     SINT    SINTvar;
   141     INT     INTvar;
   118     INT     INTvar;
   226 
   203 
   227   return ts;
   204   return ts;
   228 }
   205 }
   229 
   206 
   230 #define EPOCH_YEAR 1970
   207 #define EPOCH_YEAR 1970
   231 #define SECONDS_PER_HOUR (60 * 60)
   208 #define SECONDS_PER_MINUTE 60
       
   209 #define SECONDS_PER_HOUR (60 * SECONDS_PER_MINUTE)
   232 #define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR)
   210 #define SECONDS_PER_DAY (24 * SECONDS_PER_HOUR)
   233 #define __isleap(year) \
   211 #define __isleap(year) \
   234   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
   212   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
   235 static const unsigned short int __mon_yday[2][13] =
   213 static const unsigned short int __mon_yday[2][13] =
   236 {
   214 {
   547 static inline STRING __time_to_string(TIME IN){
   525 static inline STRING __time_to_string(TIME IN){
   548     STRING res;
   526     STRING res;
   549     div_t days;
   527     div_t days;
   550     /*t#5d14h12m18s3.5ms*/
   528     /*t#5d14h12m18s3.5ms*/
   551     res = __INIT_STRING;
   529     res = __INIT_STRING;
   552     days = div(IN.tv_sec ,86400);
   530     days = div(IN.tv_sec, SECONDS_PER_DAY);
   553     if(!days.rem && IN.tv_nsec == 0){
   531     if(!days.rem && IN.tv_nsec == 0){
   554         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd", days.quot);
   532         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd", days.quot);
   555     }else{
   533     }else{
   556         div_t hours = div(days.rem, 3600);
   534         div_t hours = div(days.rem, SECONDS_PER_HOUR);
   557         if(!hours.rem && IN.tv_nsec == 0){
   535         if(!hours.rem && IN.tv_nsec == 0){
   558             res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh", days.quot, hours.quot);
   536             res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh", days.quot, hours.quot);
   559         }else{
   537         }else{
   560             div_t minuts = div(hours.rem, 60);
   538             div_t minuts = div(hours.rem, SECONDS_PER_MINUTE);
   561             if(!minuts.rem && IN.tv_nsec == 0){
   539             if(!minuts.rem && IN.tv_nsec == 0){
   562                 res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm", days.quot, hours.quot, minuts.quot);
   540                 res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm", days.quot, hours.quot, minuts.quot);
   563             }else{
   541             }else{
   564                 if(IN.tv_nsec == 0){
   542                 if(IN.tv_nsec == 0){
   565                     res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm%ds", days.quot, hours.quot, minuts.quot, minuts.rem);
   543                     res.len = snprintf((char*)&res.body, STR_MAX_LEN, "T#%dd%dh%dm%ds", days.quot, hours.quot, minuts.quot, minuts.rem);
   601         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%2.2d",
   579         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%2.2d",
   602                  broken_down_time.tm_hour,
   580                  broken_down_time.tm_hour,
   603                  broken_down_time.tm_min,
   581                  broken_down_time.tm_min,
   604                  broken_down_time.tm_sec);
   582                  broken_down_time.tm_sec);
   605     }else{
   583     }else{
   606         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%09.6g",
   584         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "TOD#%2.2d:%2.2d:%09.6f",
   607                  broken_down_time.tm_hour,
   585                  broken_down_time.tm_hour,
   608                  broken_down_time.tm_min,
   586                  broken_down_time.tm_min,
   609                  (LREAL)broken_down_time.tm_sec + (LREAL)IN.tv_nsec / 1e9);
   587                  (LREAL)broken_down_time.tm_sec + (LREAL)IN.tv_nsec / 1e9);
   610     }
   588     }
   611     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   589     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   623                  broken_down_time.tm_day,
   601                  broken_down_time.tm_day,
   624                  broken_down_time.tm_hour,
   602                  broken_down_time.tm_hour,
   625                  broken_down_time.tm_min,
   603                  broken_down_time.tm_min,
   626                  broken_down_time.tm_sec);
   604                  broken_down_time.tm_sec);
   627     }else{
   605     }else{
   628         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%09.6g",
   606         res.len = snprintf((char*)&res.body, STR_MAX_LEN, "DT#%d-%2.2d-%2.2d-%2.2d:%2.2d:%09.6f",
   629                  broken_down_time.tm_year,
   607                  broken_down_time.tm_year,
   630                  broken_down_time.tm_mon,
   608                  broken_down_time.tm_mon,
   631                  broken_down_time.tm_day,
   609                  broken_down_time.tm_day,
   632                  broken_down_time.tm_hour,
   610                  broken_down_time.tm_hour,
   633                  broken_down_time.tm_min,
   611                  broken_down_time.tm_min,
   639 
   617 
   640     /**********************************************/
   618     /**********************************************/
   641     /*  [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME]  */
   619     /*  [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME]  */
   642     /**********************************************/
   620     /**********************************************/
   643 
   621 
   644 static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % (24*60*60), IN.tv_nsec};}
   622 static inline TOD __date_and_time_to_time_of_day(DT IN) {
   645 static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};}
   623 	return (TOD){
       
   624 		IN.tv_sec % SECONDS_PER_DAY + (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0),
       
   625 		IN.tv_nsec};
       
   626 }
       
   627 static inline DATE __date_and_time_to_date(DT IN){
       
   628 	return (DATE){
       
   629 		IN.tv_sec - IN.tv_sec % SECONDS_PER_DAY - (IN.tv_sec < 0 ? SECONDS_PER_DAY : 0),
       
   630 		0};
       
   631 }
   646 
   632 
   647     /*****************/
   633     /*****************/
   648     /*  FROM/TO BCD  */
   634     /*  FROM/TO BCD  */
   649     /*****************/
   635     /*****************/
   650 #define __bcd_digit(fac)
   636 
       
   637 static inline BOOL __test_bcd(LWORD IN) {
       
   638 	while (IN) {
       
   639 		if ((IN & 0xf) > 9) return 1;
       
   640 		IN >>= 4;
       
   641 	}
       
   642 	return 0;
       
   643 }
       
   644 
   651 static inline ULINT __bcd_to_uint(LWORD IN){
   645 static inline ULINT __bcd_to_uint(LWORD IN){
   652     ULINT res;
   646     ULINT res = IN & 0xf;
   653     ULINT i;
   647     ULINT factor = 10ULL;
   654 
   648 
   655     res = IN & 0xf;
   649     while (IN >>= 4) {
   656     for(i = 10ULL; i <= 1000000000000000ULL; i *= 10){
   650         res += (IN & 0xf) * factor;
   657         if(!(IN >>= 4))
   651         factor *= 10;
   658             break;
       
   659         res += (IN & 0xf) * i;
       
   660     }
   652     }
   661     return res;
   653     return res;
   662 }
   654 }
   663 
   655 
   664 static inline LWORD __uint_to_bcd(ULINT IN){
   656 static inline LWORD __uint_to_bcd(ULINT IN){
   665     LWORD res;
   657     LWORD res = IN % 10;
   666     USINT i;
   658     USINT shift = 4;
   667 
   659 
   668     res = IN % 10;
   660     while (IN /= 10) {
   669     for(i = 4; i<=60; i += 4){
   661         res |= (IN % 10) << shift;
   670         if(!(IN /= 10))
   662         shift += 4;
   671             break;
       
   672         res |= (IN % 10) << i;
       
   673     }
   663     }
   674     return res;
   664     return res;
   675 }
   665 }
   676 
   666 
   677 
   667 
   975 
   965 
   976 
   966 
   977 /********   BCD_TO_   ************/
   967 /********   BCD_TO_   ************/
   978 #define __iec_(to_TYPENAME,from_TYPENAME) \
   968 #define __iec_(to_TYPENAME,from_TYPENAME) \
   979 static inline to_TYPENAME from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   969 static inline to_TYPENAME from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   980   TEST_EN(to_TYPENAME)\
   970   TEST_EN_COND(to_TYPENAME, __test_bcd(op))\
   981   return (to_TYPENAME)__bcd_to_uint(op);\
   971   return (to_TYPENAME)__bcd_to_uint(op);\
   982 }\
   972 }\
   983 static inline to_TYPENAME BCD_TO_##to_TYPENAME##__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   973 static inline to_TYPENAME BCD_TO_##to_TYPENAME##__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\
   984   return from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO, op);\
   974   return from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO, op);\
   985 }
   975 }