lib/iec_std_lib.h
changeset 180 64334c5a00b1
parent 165 83963465b773
child 187 f2cd0b5236f7
equal deleted inserted replaced
179:a4eb4fd6b0d6 180:64334c5a00b1
    55 # if __WORDSIZE == 64
    55 # if __WORDSIZE == 64
    56 #define __32b_sufix
    56 #define __32b_sufix
    57 #define __64b_sufix L
    57 #define __64b_sufix L
    58 #else
    58 #else
    59 #define __32b_sufix L
    59 #define __32b_sufix L
    60 #define __64b_sufix LL 
    60 #define __64b_sufix LL
    61 #endif 
    61 #endif
    62 
    62 
    63 #define __lit(type,value,sfx) (type)value##sfx
    63 #define __lit(type,value,sfx) (type)value##sfx
    64 // Keep this macro expention step to let sfx change into L or LL 
    64 // Keep this macro expention step to let sfx change into L or LL
    65 #define __literal(type,value,sfx) __lit(type,value,sfx)
    65 #define __literal(type,value,sfx) __lit(type,value,sfx)
    66 
    66 
    67 #define __BOOL_LITERAL(value) __literal(BOOL,value,)
    67 #define __BOOL_LITERAL(value) __literal(BOOL,value,)
    68 #define __SINT_LITERAL(value) __literal(SINT,value,)
    68 #define __SINT_LITERAL(value) __literal(SINT,value,)
    69 #define __INT_LITERAL(value) __literal(INT,value,)
    69 #define __INT_LITERAL(value) __literal(INT,value,)
   159   }
   159   }
   160 }
   160 }
   161 
   161 
   162 static inline struct timespec __time_to_timespec(int sign, double mseconds, double seconds, double minutes, double hours, double days) {
   162 static inline struct timespec __time_to_timespec(int sign, double mseconds, double seconds, double minutes, double hours, double days) {
   163   struct timespec ts;
   163   struct timespec ts;
   164   
   164 
   165   /* sign is 1 for positive values, -1 for negative time... */
   165   /* sign is 1 for positive values, -1 for negative time... */
   166   long double total_sec = ((days*24 + hours)*60 + minutes)*60 + seconds + mseconds/1e3;
   166   long double total_sec = ((days*24 + hours)*60 + minutes)*60 + seconds + mseconds/1e3;
   167   if (sign >= 0) sign = 1; else sign = -1;
   167   if (sign >= 0) sign = 1; else sign = -1;
   168   ts.tv_sec = sign * (long int)total_sec;
   168   ts.tv_sec = sign * (long int)total_sec;
   169   ts.tv_nsec = sign * (long int)((total_sec - ts.tv_sec)*1e9);
   169   ts.tv_nsec = sign * (long int)((total_sec - ts.tv_sec)*1e9);
   172 }
   172 }
   173 
   173 
   174 
   174 
   175 static inline struct timespec __tod_to_timespec(double seconds, double minutes, double hours) {
   175 static inline struct timespec __tod_to_timespec(double seconds, double minutes, double hours) {
   176   struct timespec ts;
   176   struct timespec ts;
   177   
   177 
   178   long double total_sec = (hours*60 + minutes)*60 + seconds;
   178   long double total_sec = (hours*60 + minutes)*60 + seconds;
   179   ts.tv_sec = (long int)total_sec;
   179   ts.tv_sec = (long int)total_sec;
   180   ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
   180   ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
   181   
   181 
   182   return ts;
   182   return ts;
   183 }
   183 }
   184 
   184 
   185 static inline struct timespec __date_to_timespec(int day, int month, int year) {
   185 static inline struct timespec __date_to_timespec(int day, int month, int year) {
   186   struct timespec ts;
   186   struct timespec ts;
   198   if ((time_t)(-1) == epoch_seconds)
   198   if ((time_t)(-1) == epoch_seconds)
   199     IEC_error();
   199     IEC_error();
   200 
   200 
   201   ts.tv_sec = epoch_seconds;
   201   ts.tv_sec = epoch_seconds;
   202   ts.tv_nsec = 0;
   202   ts.tv_nsec = 0;
   203   
   203 
   204   return ts;
   204   return ts;
   205 }
   205 }
   206 
   206 
   207 static inline struct timespec __dt_to_timespec(double seconds,  double minutes, double hours, int day, int month, int year) {
   207 static inline struct timespec __dt_to_timespec(double seconds,  double minutes, double hours, int day, int month, int year) {
   208   struct timespec ts;
   208   struct timespec ts;
   209   
   209 
   210   long double total_sec = (hours*60 + minutes)*60 + seconds;
   210   long double total_sec = (hours*60 + minutes)*60 + seconds;
   211   ts.tv_sec = (long int)total_sec;
   211   ts.tv_sec = (long int)total_sec;
   212   ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
   212   ts.tv_nsec = (long int)((total_sec - ts.tv_sec)*1e9);
   213 
   213 
   214   struct tm broken_down_time;
   214   struct tm broken_down_time;
   254     *ENO = __BOOL_LITERAL(TRUE);
   254     *ENO = __BOOL_LITERAL(TRUE);
   255 
   255 
   256 /***************/
   256 /***************/
   257 /*   Time ops  */
   257 /*   Time ops  */
   258 /***************/
   258 /***************/
   259 #define __TIME_CMP(t1, t2) (t2.tv_sec == t1.tv_sec ? t1.tv_nsec - t2.tv_nsec : t1.tv_sec - t2.tv_sec) 
   259 #define __TIME_CMP(t1, t2) (t2.tv_sec == t1.tv_sec ? t1.tv_nsec - t2.tv_nsec : t1.tv_sec - t2.tv_sec)
   260 
   260 
   261 static inline TIME __TIME_ADD(TIME IN1, TIME IN2){
   261 static inline TIME __TIME_ADD(TIME IN1, TIME IN2){
   262   TIME res ={IN1.tv_sec + IN2.tv_sec,
   262   TIME res ={IN1.tv_sec + IN2.tv_sec,
   263              IN1.tv_nsec + IN2.tv_nsec };
   263              IN1.tv_nsec + IN2.tv_nsec };
   264   __normalize_timespec(&res);
   264   __normalize_timespec(&res);
   374 }
   374 }
   375 static inline STRING __insert(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t P){
   375 static inline STRING __insert(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t P){
   376     TEST_EN_COND(STRING, P < 0)
   376     TEST_EN_COND(STRING, P < 0)
   377     STRING res = __INIT_STRING;
   377     STRING res = __INIT_STRING;
   378     __strlen_t to_copy;
   378     __strlen_t to_copy;
   379     
   379 
   380     to_copy = P > IN1.len ? IN1.len : P - 1;
   380     to_copy = P > IN1.len ? IN1.len : P - 1;
   381     memcpy(&res.body, &IN1.body , to_copy);
   381     memcpy(&res.body, &IN1.body , to_copy);
   382     P = res.len = to_copy;
   382     P = res.len = to_copy;
   383     
   383 
   384     to_copy = IN2.len + res.len > STR_MAX_LEN ? STR_MAX_LEN - res.len : IN2.len;
   384     to_copy = IN2.len + res.len > STR_MAX_LEN ? STR_MAX_LEN - res.len : IN2.len;
   385     memcpy(&res.body[res.len], &IN2.body , to_copy);
   385     memcpy(&res.body[res.len], &IN2.body , to_copy);
   386     res.len += to_copy;
   386     res.len += to_copy;
   387 
   387 
   388     to_copy = IN1.len - P < STR_MAX_LEN - res.len ? IN1.len - P : STR_MAX_LEN - res.len ;
   388     to_copy = IN1.len - P < STR_MAX_LEN - res.len ? IN1.len - P : STR_MAX_LEN - res.len ;
   393 }
   393 }
   394 static inline STRING __delete(EN_ENO_PARAMS, STRING IN, __strlen_t L, __strlen_t P){
   394 static inline STRING __delete(EN_ENO_PARAMS, STRING IN, __strlen_t L, __strlen_t P){
   395     TEST_EN_COND(STRING, L < 0 || P < 0)
   395     TEST_EN_COND(STRING, L < 0 || P < 0)
   396     STRING res = __INIT_STRING;
   396     STRING res = __INIT_STRING;
   397     __strlen_t to_copy;
   397     __strlen_t to_copy;
   398     
   398 
   399     to_copy = P > IN.len ? IN.len : P-1;
   399     to_copy = P > IN.len ? IN.len : P-1;
   400     memcpy(&res.body, &IN.body , to_copy);
   400     memcpy(&res.body, &IN.body , to_copy);
   401     P = res.len = to_copy;
   401     P = res.len = to_copy;
   402 
   402 
   403     if( IN.len > P + L ){
   403     if( IN.len > P + L ){
   410 }
   410 }
   411 static inline STRING __replace(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t L, __strlen_t P){
   411 static inline STRING __replace(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t L, __strlen_t P){
   412     TEST_EN_COND(STRING, L < 0 || P < 0)
   412     TEST_EN_COND(STRING, L < 0 || P < 0)
   413     STRING res = __INIT_STRING;
   413     STRING res = __INIT_STRING;
   414     __strlen_t to_copy;
   414     __strlen_t to_copy;
   415     
   415 
   416     to_copy = P > IN1.len ? IN1.len : P-1;
   416     to_copy = P > IN1.len ? IN1.len : P-1;
   417     memcpy(&res.body, &IN1.body , to_copy);
   417     memcpy(&res.body, &IN1.body , to_copy);
   418     P = res.len = to_copy;
   418     P = res.len = to_copy;
   419     
   419 
   420     to_copy = IN2.len < L ? IN2.len : L;
   420     to_copy = IN2.len < L ? IN2.len : L;
   421 
   421 
   422     if( to_copy + res.len > STR_MAX_LEN ) 
   422     if( to_copy + res.len > STR_MAX_LEN )
   423        to_copy = STR_MAX_LEN - res.len;   
   423        to_copy = STR_MAX_LEN - res.len;
   424 
   424 
   425     memcpy(&res.body[res.len], &IN2.body , to_copy);
   425     memcpy(&res.body[res.len], &IN2.body , to_copy);
   426     res.len += to_copy;
   426     res.len += to_copy;
   427 
   427 
   428     P += L;
   428     P += L;
   444     while(count1 + count2 < IN1->len && count2 < IN2->len)
   444     while(count1 + count2 < IN1->len && count2 < IN2->len)
   445     {
   445     {
   446         if(IN1->body[count1 + count2] != IN2->body[count2++]){
   446         if(IN1->body[count1 + count2] != IN2->body[count2++]){
   447             count1 += count2;
   447             count1 += count2;
   448             count2 = 0;
   448             count2 = 0;
   449         }        
   449         }
   450     }
   450     }
   451     return count2 == IN2->len -1 ? 0 : count1 + 1;
   451     return count2 == IN2->len -1 ? 0 : count1 + 1;
   452 }
   452 }
   453 static inline __strlen_t __find(EN_ENO_PARAMS, STRING IN1, STRING IN2){
   453 static inline __strlen_t __find(EN_ENO_PARAMS, STRING IN1, STRING IN2){
   454     TEST_EN(UINT)
   454     TEST_EN(UINT)
   508     LINT res = 0;
   508     LINT res = 0;
   509     char tmp[STR_MAX_LEN];
   509     char tmp[STR_MAX_LEN];
   510     char tmp2[STR_MAX_LEN];
   510     char tmp2[STR_MAX_LEN];
   511     __strlen_t l;
   511     __strlen_t l;
   512     unsigned int shift = 0;
   512     unsigned int shift = 0;
   513     
   513 
   514     if(IN->body[0]=='2' && IN->body[1]=='#'){
   514     if(IN->body[0]=='2' && IN->body[1]=='#'){
   515         /* 2#0101_1010_1011_1111 */
   515         /* 2#0101_1010_1011_1111 */
   516         for(l = IN->len - 1; l >= 2 && shift < 64; l--)
   516         for(l = IN->len - 1; l >= 2 && shift < 64; l--)
   517         {
   517         {
   518             char c = IN->body[l];
   518             char c = IN->body[l];
   559                 shift += 1;
   559                 shift += 1;
   560             }else if( c >= '.' ){ /* reset value */
   560             }else if( c >= '.' ){ /* reset value */
   561                 res = 0;
   561                 res = 0;
   562                 fac = IN->body[0] == '-' ? -1 : 1;
   562                 fac = IN->body[0] == '-' ? -1 : 1;
   563                 shift = 0;
   563                 shift = 0;
   564             }            
   564             }
   565         }
   565         }
   566     }
   566     }
   567     return res;
   567     return res;
   568 }
   568 }
   569 
   569 
   586     while(--l > 0 && IN.body[l] != '.');
   586     while(--l > 0 && IN.body[l] != '.');
   587     if(l != 0){
   587     if(l != 0){
   588         return atof((const char *)&IN.body);
   588         return atof((const char *)&IN.body);
   589     }else{
   589     }else{
   590         return (LREAL)__pstring_to_sint(&IN);
   590         return (LREAL)__pstring_to_sint(&IN);
   591     }    
   591     }
   592 }
   592 }
   593 
   593 
   594     /***************/
   594     /***************/
   595     /*   TO_TIME   */
   595     /*   TO_TIME   */
   596     /***************/
   596     /***************/
   736     }
   736     }
   737     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   737     if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN;
   738     return res;
   738     return res;
   739 }
   739 }
   740     /* BCD */
   740     /* BCD */
   741 #define __bcd_digit(fac) 
   741 #define __bcd_digit(fac)
   742 static inline ULINT __bcd_to_uint(EN_ENO_PARAMS, LWORD IN){
   742 static inline ULINT __bcd_to_uint(EN_ENO_PARAMS, LWORD IN){
   743     TEST_EN(ULINT)
   743     TEST_EN(ULINT)
   744     return IN & 0xf +
   744     return IN & 0xf +
   745            !(IN >>= 4) ? 0 : IN & 0xf * 10ULL + 
   745            !(IN >>= 4) ? 0 : IN & 0xf * 10ULL +
   746            !(IN >>= 4) ? 0 : IN & 0xf * 100ULL + 
   746            !(IN >>= 4) ? 0 : IN & 0xf * 100ULL +
   747            !(IN >>= 4) ? 0 : IN & 0xf * 1000ULL + 
   747            !(IN >>= 4) ? 0 : IN & 0xf * 1000ULL +
   748            !(IN >>= 4) ? 0 : IN & 0xf * 10000ULL + 
   748            !(IN >>= 4) ? 0 : IN & 0xf * 10000ULL +
   749            !(IN >>= 4) ? 0 : IN & 0xf * 100000ULL + 
   749            !(IN >>= 4) ? 0 : IN & 0xf * 100000ULL +
   750            !(IN >>= 4) ? 0 : IN & 0xf * 1000000ULL + 
   750            !(IN >>= 4) ? 0 : IN & 0xf * 1000000ULL +
   751            !(IN >>= 4) ? 0 : IN & 0xf * 10000000ULL + 
   751            !(IN >>= 4) ? 0 : IN & 0xf * 10000000ULL +
   752            !(IN >>= 4) ? 0 : IN & 0xf * 100000000ULL + 
   752            !(IN >>= 4) ? 0 : IN & 0xf * 100000000ULL +
   753            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000ULL + 
   753            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000ULL +
   754            !(IN >>= 4) ? 0 : IN & 0xf * 10000000000ULL + 
   754            !(IN >>= 4) ? 0 : IN & 0xf * 10000000000ULL +
   755            !(IN >>= 4) ? 0 : IN & 0xf * 100000000000ULL + 
   755            !(IN >>= 4) ? 0 : IN & 0xf * 100000000000ULL +
   756            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000000ULL + 
   756            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000000ULL +
   757            !(IN >>= 4) ? 0 : IN & 0xf * 10000000000000ULL + 
   757            !(IN >>= 4) ? 0 : IN & 0xf * 10000000000000ULL +
   758            !(IN >>= 4) ? 0 : IN & 0xf * 100000000000000ULL + 
   758            !(IN >>= 4) ? 0 : IN & 0xf * 100000000000000ULL +
   759            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000000000ULL;
   759            !(IN >>= 4) ? 0 : IN & 0xf * 1000000000000000ULL;
   760            
   760 
   761 }
   761 }
   762 static inline LWORD __uint_to_bcd(EN_ENO_PARAMS, ULINT IN){
   762 static inline LWORD __uint_to_bcd(EN_ENO_PARAMS, ULINT IN){
   763     TEST_EN(LWORD)
   763     TEST_EN(LWORD)
   764     return (IN - (IN /= 10))|
   764     return (IN - (IN /= 10))|
   765            (IN - (IN /= 10)) << 4 |
   765            (IN - (IN /= 10)) << 4 |
   777            (IN - (IN /= 10)) << 52 |
   777            (IN - (IN /= 10)) << 52 |
   778            (IN - (IN /= 10)) << 56 |
   778            (IN - (IN /= 10)) << 56 |
   779            (IN - (IN /= 10)) << 60;
   779            (IN - (IN /= 10)) << 60;
   780 }
   780 }
   781 
   781 
   782 /* workaround for va-atgs limitation on shorter that int params */    
   782 /* workaround for va-atgs limitation on shorter that int params */
   783 #define VA_ARGS_REAL LREAL
   783 #define VA_ARGS_REAL LREAL
   784 #define VA_ARGS_LREAL LREAL
   784 #define VA_ARGS_LREAL LREAL
   785 #define VA_ARGS_SINT DINT
   785 #define VA_ARGS_SINT DINT
   786 #define VA_ARGS_INT DINT
   786 #define VA_ARGS_INT DINT
   787 #define VA_ARGS_DINT DINT
   787 #define VA_ARGS_DINT DINT
   880 /**************/
   880 /**************/
   881 static inline BOOL __xor_BOOL(EN_ENO_PARAMS, UINT param_count, BOOL op1, ...){
   881 static inline BOOL __xor_BOOL(EN_ENO_PARAMS, UINT param_count, BOOL op1, ...){
   882   TEST_EN(BOOL)
   882   TEST_EN(BOOL)
   883   va_list ap;
   883   va_list ap;
   884   UINT i;
   884   UINT i;
   885   
   885 
   886   va_start (ap, op1);         /* Initialize the argument list.  */
   886   va_start (ap, op1);         /* Initialize the argument list.  */
   887   
   887 
   888   for (i = 0; i < param_count - 1; i++){
   888   for (i = 0; i < param_count - 1; i++){
   889     BOOL tmp = va_arg (ap, VA_ARGS_BOOL);
   889     BOOL tmp = va_arg (ap, VA_ARGS_BOOL);
   890     op1 = (op1 && !tmp) || (!op1 && tmp);
   890     op1 = (op1 && !tmp) || (!op1 && tmp);
   891   }
   891   }
   892   
   892 
   893   va_end (ap);                  /* Clean up.  */
   893   va_end (ap);                  /* Clean up.  */
   894   return op1;
   894   return op1;
   895 }
   895 }
   896 #define __xor_(TYPENAME) __arith_expand(__xor_, TYPENAME, ^)
   896 #define __xor_(TYPENAME) __arith_expand(__xor_, TYPENAME, ^)
   897 ANY_NBIT(__xor_)
   897 ANY_NBIT(__xor_)
   967 }
   967 }
   968 
   968 
   969   /**************/
   969   /**************/
   970   /*    ABS     */
   970   /*    ABS     */
   971   /**************/
   971   /**************/
   972 #define __abs_(TYPENAME) __numeric(__abs_, TYPENAME, abs)
   972 #define __abs_(TYPENAME) \
       
   973 static inline TYPENAME __abs_##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\
       
   974   TEST_EN(TYPENAME)\
       
   975   if (op < 0)\
       
   976     return -op;\
       
   977   return op;\
       
   978 }
   973 ANY_NUM(__abs_)
   979 ANY_NUM(__abs_)
   974 
   980 
   975   /**************/
   981   /**************/
   976   /*    SQRT    */
   982   /*    SQRT    */
   977   /**************/
   983   /**************/