221 broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ |
262 broken_down_time.tm_mon = month - 1; /* month since January, in the range 0 to 11 */ |
222 broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ |
263 broken_down_time.tm_year = year - 1900; /* number of years since 1900 */ |
223 |
264 |
224 epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ |
265 epoch_seconds = mktime(&broken_down_time); /* determine number of seconds since the epoch, i.e. Jan 1st 1970 */ |
225 if ((time_t)(-1) == epoch_seconds) |
266 if ((time_t)(-1) == epoch_seconds) |
226 IEC_error(); |
267 __iec_error(); |
227 |
268 |
228 ts.tv_sec += epoch_seconds; |
269 ts.tv_sec += epoch_seconds; |
229 if (ts.tv_sec < epoch_seconds) |
270 if (ts.tv_sec < epoch_seconds) |
230 /* since the TOD is always positive, if the above happens then we had an overflow */ |
271 /* since the TOD is always positive, if the above happens then we had an overflow */ |
231 IEC_error(); |
272 __iec_error(); |
232 |
273 |
233 return ts; |
274 return ts; |
234 } |
275 } |
235 |
276 |
236 /********************/ |
277 /*******************/ |
237 /* EN/ENO PARAMS */ |
278 /* Time operations */ |
238 /********************/ |
279 /*******************/ |
239 |
280 |
240 #define EN_ENO_PARAMS BOOL EN, BOOL *ENO |
281 #define __time_cmp(t1, t2) (t2.tv_sec == t1.tv_sec ? t1.tv_nsec - t2.tv_nsec : t1.tv_sec - t2.tv_sec) |
241 #define TEST_EN(TYPENAME)\ |
282 |
242 if (!EN) {\ |
283 static inline TIME __time_add(TIME IN1, TIME IN2){ |
243 if (ENO != NULL)\ |
|
244 *ENO = __BOOL_LITERAL(FALSE);\ |
|
245 return __INIT_##TYPENAME;\ |
|
246 }\ |
|
247 else if (ENO != NULL)\ |
|
248 *ENO = __BOOL_LITERAL(TRUE); |
|
249 #define TEST_EN_COND(TYPENAME, COND)\ |
|
250 if (!EN || (COND)) {\ |
|
251 if (ENO != NULL)\ |
|
252 *ENO = __BOOL_LITERAL(FALSE);\ |
|
253 return __INIT_##TYPENAME;\ |
|
254 }\ |
|
255 else if (ENO != NULL)\ |
|
256 *ENO = __BOOL_LITERAL(TRUE); |
|
257 |
|
258 /***************/ |
|
259 /* Time ops */ |
|
260 /***************/ |
|
261 #define __TIME_CMP(t1, t2) (t2.tv_sec == t1.tv_sec ? t1.tv_nsec - t2.tv_nsec : t1.tv_sec - t2.tv_sec) |
|
262 |
|
263 static inline TIME __TIME_ADD(TIME IN1, TIME IN2){ |
|
264 TIME res ={IN1.tv_sec + IN2.tv_sec, |
284 TIME res ={IN1.tv_sec + IN2.tv_sec, |
265 IN1.tv_nsec + IN2.tv_nsec }; |
285 IN1.tv_nsec + IN2.tv_nsec }; |
266 __normalize_timespec(&res); |
286 __normalize_timespec(&res); |
267 return res; |
287 return res; |
268 } |
288 } |
269 static inline TIME __TIME_SUB(TIME IN1, TIME IN2){ |
289 static inline TIME __time_sub(TIME IN1, TIME IN2){ |
270 TIME res ={IN1.tv_sec - IN2.tv_sec, |
290 TIME res ={IN1.tv_sec - IN2.tv_sec, |
271 IN1.tv_nsec - IN2.tv_nsec }; |
291 IN1.tv_nsec - IN2.tv_nsec }; |
272 __normalize_timespec(&res); |
292 __normalize_timespec(&res); |
273 return res; |
293 return res; |
274 } |
294 } |
275 static inline TIME __TIME_MUL(TIME IN1, LREAL IN2){ |
295 static inline TIME __time_mul(TIME IN1, LREAL IN2){ |
276 LREAL s_f = IN1.tv_sec * IN2; |
296 LREAL s_f = IN1.tv_sec * IN2; |
277 time_t s = s_f; |
297 time_t s = s_f; |
278 div_t ns = div((LREAL)IN1.tv_nsec * IN2, 1000000000); |
298 div_t ns = div((LREAL)IN1.tv_nsec * IN2, 1000000000); |
279 TIME res = {s + ns.quot, |
299 TIME res = {s + ns.quot, |
280 ns.rem + (s_f - s) * 1000000000 }; |
300 ns.rem + (s_f - s) * 1000000000 }; |
281 __normalize_timespec(&res); |
301 __normalize_timespec(&res); |
282 return res; |
302 return res; |
283 } |
303 } |
284 static inline TIME __TIME_DIV(TIME IN1, LREAL IN2){ |
304 static inline TIME __time_div(TIME IN1, LREAL IN2){ |
285 LREAL s_f = IN1.tv_sec / IN2; |
305 LREAL s_f = IN1.tv_sec / IN2; |
286 time_t s = s_f; |
306 time_t s = s_f; |
287 TIME res = {s, |
307 TIME res = {s, |
288 IN1.tv_nsec / IN2 + (s_f - s) * 1000000000 }; |
308 IN1.tv_nsec / IN2 + (s_f - s) * 1000000000 }; |
289 __normalize_timespec(&res); |
309 __normalize_timespec(&res); |
290 return res; |
310 return res; |
291 } |
311 } |
292 |
312 |
293 static inline TIME __date_and_time_to_time_of_day(EN_ENO_PARAMS, TIME IN){ |
|
294 TEST_EN(TIME) |
|
295 return (TIME){IN.tv_sec % 86400, IN.tv_nsec}; |
|
296 } |
|
297 static inline TIME __date_and_time_to_date(EN_ENO_PARAMS, TIME IN){ |
|
298 TEST_EN(TIME) |
|
299 return (TIME){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0}; |
|
300 } |
|
301 static inline TIME __time_add(EN_ENO_PARAMS, TIME IN1, TIME IN2){ |
|
302 TEST_EN(TIME) |
|
303 return __TIME_ADD(IN1, IN2); |
|
304 } |
|
305 static inline TIME __time_sub(EN_ENO_PARAMS, TIME IN1, TIME IN2){ |
|
306 TEST_EN(TIME) |
|
307 return __TIME_SUB(IN1, IN2); |
|
308 } |
|
309 static inline TIME __time_mul(EN_ENO_PARAMS, TIME IN1, LREAL IN2){ |
|
310 TEST_EN(TIME) |
|
311 return __TIME_MUL(IN1, IN2); |
|
312 } |
|
313 static inline TIME __time_div(EN_ENO_PARAMS, TIME IN1, LREAL IN2){ |
|
314 TEST_EN(TIME) |
|
315 return __TIME_DIV(IN1, IN2); |
|
316 } |
|
317 |
|
318 /***************/ |
|
319 /* String ops */ |
|
320 /***************/ |
|
321 #define __STR_CMP(str1, str2) memcmp((char*)&str1.body,(char*)&str2.body, str1.len < str2.len ? str1.len : str2.len) |
|
322 |
|
323 static inline __strlen_t __len(EN_ENO_PARAMS, STRING IN){ |
|
324 TEST_EN(UINT) |
|
325 return IN.len; |
|
326 } |
|
327 static inline STRING __left(EN_ENO_PARAMS, STRING IN, __strlen_t L){ |
|
328 STRING res; |
|
329 TEST_EN_COND(STRING, L < 0) |
|
330 res = __INIT_STRING; |
|
331 L = L < IN.len ? L : IN.len; |
|
332 memcpy(&res.body, &IN.body, L); |
|
333 res.len = L; |
|
334 return res; |
|
335 } |
|
336 static inline STRING __right(EN_ENO_PARAMS, STRING IN, __strlen_t L){ |
|
337 STRING res; |
|
338 TEST_EN_COND(STRING, L < 0) |
|
339 res = __INIT_STRING; |
|
340 L = L < IN.len ? L : IN.len; |
|
341 memcpy(&res.body, &IN.body[IN.len - L], L); |
|
342 res.len = L; |
|
343 return res; |
|
344 } |
|
345 static inline STRING __mid(EN_ENO_PARAMS, STRING IN, __strlen_t L, __strlen_t P){ |
|
346 STRING res; |
|
347 TEST_EN_COND(STRING, L < 0 || P < 0) |
|
348 res = __INIT_STRING; |
|
349 if(P <= IN.len){ |
|
350 P -= 1; /* now can be used as [index]*/ |
|
351 L = L + P <= IN.len ? L : IN.len - P; |
|
352 memcpy(&res.body, &IN.body[P] , L); |
|
353 res.len = L; |
|
354 } |
|
355 return res; |
|
356 } |
|
357 static inline STRING __concat(EN_ENO_PARAMS, UINT param_count, ...){ |
|
358 UINT i; |
|
359 STRING res; |
|
360 va_list ap; |
|
361 __strlen_t charcount; |
|
362 TEST_EN(STRING) |
|
363 charcount = 0; |
|
364 res = __INIT_STRING; |
|
365 |
|
366 va_start (ap, param_count); /* Initialize the argument list. */ |
|
367 |
|
368 for (i = 0; i < param_count && charcount < STR_MAX_LEN; i++) |
|
369 { |
|
370 STRING tmp = va_arg(ap, STRING); |
|
371 __strlen_t charrem = STR_MAX_LEN - charcount; |
|
372 __strlen_t to_write = tmp.len > charrem ? charrem : tmp.len; |
|
373 memcpy(&res.body[charcount], &tmp.body , to_write); |
|
374 charcount += to_write; |
|
375 } |
|
376 |
|
377 res.len = charcount; |
|
378 |
|
379 va_end (ap); /* Clean up. */ |
|
380 return res; |
|
381 } |
|
382 static inline STRING __insert(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t P){ |
|
383 STRING res; |
|
384 __strlen_t to_copy; |
|
385 TEST_EN_COND(STRING, P < 0) |
|
386 res = __INIT_STRING; |
|
387 |
|
388 to_copy = P > IN1.len ? IN1.len : P; |
|
389 memcpy(&res.body, &IN1.body , to_copy); |
|
390 P = res.len = to_copy; |
|
391 |
|
392 to_copy = IN2.len + res.len > STR_MAX_LEN ? STR_MAX_LEN - res.len : IN2.len; |
|
393 memcpy(&res.body[res.len], &IN2.body , to_copy); |
|
394 res.len += to_copy; |
|
395 |
|
396 to_copy = IN1.len - P < STR_MAX_LEN - res.len ? IN1.len - P : STR_MAX_LEN - res.len ; |
|
397 memcpy(&res.body[res.len], &IN1.body[P] , to_copy); |
|
398 res.len += to_copy; |
|
399 |
|
400 return res; |
|
401 } |
|
402 static inline STRING __delete(EN_ENO_PARAMS, STRING IN, __strlen_t L, __strlen_t P){ |
|
403 STRING res; |
|
404 __strlen_t to_copy; |
|
405 TEST_EN_COND(STRING, L < 0 || P < 0) |
|
406 res = __INIT_STRING; |
|
407 |
|
408 to_copy = P > IN.len ? IN.len : P-1; |
|
409 memcpy(&res.body, &IN.body , to_copy); |
|
410 P = res.len = to_copy; |
|
411 |
|
412 if( IN.len > P + L ){ |
|
413 to_copy = IN.len - P - L; |
|
414 memcpy(&res.body[res.len], &IN.body[P + L], to_copy); |
|
415 res.len += to_copy; |
|
416 } |
|
417 |
|
418 return res; |
|
419 } |
|
420 static inline STRING __replace(EN_ENO_PARAMS, STRING IN1, STRING IN2, __strlen_t L, __strlen_t P){ |
|
421 STRING res; |
|
422 __strlen_t to_copy; |
|
423 TEST_EN_COND(STRING, L < 0 || P < 0) |
|
424 res = __INIT_STRING; |
|
425 |
|
426 to_copy = P > IN1.len ? IN1.len : P-1; |
|
427 memcpy(&res.body, &IN1.body , to_copy); |
|
428 P = res.len = to_copy; |
|
429 |
|
430 to_copy = IN2.len < L ? IN2.len : L; |
|
431 |
|
432 if( to_copy + res.len > STR_MAX_LEN ) |
|
433 to_copy = STR_MAX_LEN - res.len; |
|
434 |
|
435 memcpy(&res.body[res.len], &IN2.body , to_copy); |
|
436 res.len += to_copy; |
|
437 |
|
438 P += L; |
|
439 if( res.len < STR_MAX_LEN && P < IN1.len) |
|
440 { |
|
441 to_copy = IN1.len - P; |
|
442 memcpy(&res.body[res.len], &IN1.body[P] , to_copy); |
|
443 res.len += to_copy; |
|
444 } |
|
445 |
|
446 return res; |
|
447 } |
|
448 |
|
449 |
|
450 |
|
451 static inline __strlen_t __pfind(STRING* IN1, STRING* IN2){ |
|
452 UINT count1 = 0; /* offset of first matching char in IN1 */ |
|
453 UINT count2 = 0; /* count of matching char */ |
|
454 while(count1 + count2 < IN1->len && count2 < IN2->len) |
|
455 { |
|
456 if(IN1->body[count1 + count2] != IN2->body[count2]){ |
|
457 count1 += count2 + 1; |
|
458 count2 = 0; |
|
459 } |
|
460 else { |
|
461 count2++; |
|
462 } |
|
463 } |
|
464 return count2 == IN2->len -1 ? 0 : count1 + 1; |
|
465 } |
|
466 static inline __strlen_t __find(EN_ENO_PARAMS, STRING IN1, STRING IN2){ |
|
467 TEST_EN(UINT) |
|
468 return __pfind(&IN1, &IN2); |
|
469 } |
|
470 |
313 |
471 /***************/ |
314 /***************/ |
472 /* Convertions */ |
315 /* Convertions */ |
473 /***************/ |
316 /***************/ |
474 /*****************/ |
317 /*****************/ |
475 /* REAL_TO_INT */ |
318 /* REAL_TO_INT */ |
476 /*****************/ |
319 /*****************/ |
477 static inline LINT __real_round(LREAL IN) |
320 static inline LINT __real_round(LREAL IN) { |
478 { |
|
479 return fmod(IN, 1) == 0 ? ((LINT)IN / 2) * 2 : (LINT)IN; |
321 return fmod(IN, 1) == 0 ? ((LINT)IN / 2) * 2 : (LINT)IN; |
480 } |
322 } |
481 static inline LINT __preal_to_sint(LREAL IN) |
323 static inline LINT __preal_to_sint(LREAL IN) { |
482 { |
|
483 return IN >= 0 ? __real_round(IN + 0.5) : __real_round(IN - 0.5); |
324 return IN >= 0 ? __real_round(IN + 0.5) : __real_round(IN - 0.5); |
484 } |
325 } |
485 static inline LINT __preal_to_uint(LREAL IN) |
326 static inline LINT __preal_to_uint(LREAL IN) { |
486 { |
|
487 return IN >= 0 ? __real_round(IN + 0.5) : 0; |
327 return IN >= 0 ? __real_round(IN + 0.5) : 0; |
488 } |
328 } |
489 static inline LINT __real_to_sint(EN_ENO_PARAMS, LREAL IN){ |
329 static inline LINT __real_to_sint(LREAL IN) {return (LINT)__preal_to_sint(IN);} |
490 TEST_EN(LINT) |
330 static inline LWORD __real_to_bit(LREAL IN) {return (LWORD)__preal_to_uint(IN);} |
491 return (LINT)__preal_to_sint(IN); |
331 static inline ULINT __real_to_uint(LREAL IN) {return (ULINT)__preal_to_uint(IN);} |
492 } |
332 |
493 static inline LWORD __real_to_bit(EN_ENO_PARAMS, LREAL IN){ |
|
494 TEST_EN(LWORD) |
|
495 return (LWORD)__preal_to_uint(IN); |
|
496 } |
|
497 static inline ULINT __real_to_uint(EN_ENO_PARAMS, LREAL IN){ |
|
498 TEST_EN(ULINT) |
|
499 return (ULINT)__preal_to_uint(IN); |
|
500 } |
|
501 /***************/ |
333 /***************/ |
502 /* TO_STRING */ |
334 /* TO_STRING */ |
503 /***************/ |
335 /***************/ |
504 static inline STRING __bool_to_string(EN_ENO_PARAMS, BOOL IN) |
336 static inline STRING __bool_to_string(BOOL IN) { |
505 { |
337 if(IN) return (STRING){4, "TRUE"}; |
506 TEST_EN(STRING) |
|
507 if(IN) |
|
508 return (STRING){4, "TRUE"}; |
|
509 return (STRING){5,"FALSE"}; |
338 return (STRING){5,"FALSE"}; |
510 } |
339 } |
511 static inline STRING __bit_to_string(EN_ENO_PARAMS, LWORD IN){ |
340 static inline STRING __bit_to_string(LWORD IN) { |
512 STRING res; |
341 STRING res; |
513 TEST_EN(STRING) |
|
514 res = __INIT_STRING; |
342 res = __INIT_STRING; |
515 res.len = snprintf((char*)res.body, STR_MAX_LEN, "16#%llx", IN); |
343 res.len = snprintf((char*)res.body, STR_MAX_LEN, "16#%llx", IN); |
516 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
344 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
517 return res; |
345 return res; |
518 } |
346 } |
519 static inline STRING __real_to_string(EN_ENO_PARAMS, LREAL IN){ |
347 static inline STRING __real_to_string(LREAL IN) { |
520 STRING res; |
348 STRING res; |
521 TEST_EN(STRING) |
|
522 res = __INIT_STRING; |
349 res = __INIT_STRING; |
523 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%.10g", IN); |
350 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%.10g", IN); |
524 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
351 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
525 return res; |
352 return res; |
526 } |
353 } |
527 static inline STRING __sint_to_string(EN_ENO_PARAMS, LINT IN){ |
354 static inline STRING __sint_to_string(LINT IN) { |
528 STRING res; |
355 STRING res; |
529 TEST_EN(STRING) |
|
530 res = __INIT_STRING; |
356 res = __INIT_STRING; |
531 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%lld", IN); |
357 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%lld", IN); |
532 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
358 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
533 return res; |
359 return res; |
534 } |
360 } |
535 static inline STRING __uint_to_string(EN_ENO_PARAMS, ULINT IN){ |
361 static inline STRING __uint_to_string(ULINT IN) { |
536 STRING res; |
362 STRING res; |
537 TEST_EN(STRING) |
|
538 res = __INIT_STRING; |
363 res = __INIT_STRING; |
539 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%llu", IN); |
364 res.len = snprintf((char*)res.body, STR_MAX_LEN, "%llu", IN); |
540 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
365 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
541 return res; |
366 return res; |
542 } |
367 } |
543 /***************/ |
368 /***************/ |
544 /* FROM_STRING */ |
369 /* FROM_STRING */ |
545 /***************/ |
370 /***************/ |
546 static inline BOOL __string_to_bool(EN_ENO_PARAMS, STRING IN){ |
371 static inline BOOL __string_to_bool(STRING IN) { |
547 TEST_EN(BOOL) |
|
548 return IN.len == 5 ? !memcmp(&IN.body,"TRUE", IN.len) : 0; |
372 return IN.len == 5 ? !memcmp(&IN.body,"TRUE", IN.len) : 0; |
549 } |
373 } |
550 |
374 |
551 static inline LINT __pstring_to_sint(STRING* IN){ |
375 static inline LINT __pstring_to_sint(STRING* IN) { |
552 LINT res = 0; |
376 LINT res = 0; |
553 __strlen_t l; |
377 __strlen_t l; |
554 unsigned int shift = 0; |
378 unsigned int shift = 0; |
555 |
379 |
556 if(IN->body[0]=='2' && IN->body[1]=='#'){ |
380 if(IN->body[0]=='2' && IN->body[1]=='#'){ |
786 (LREAL)broken_down_time->tm_sec + ((LREAL)IN.tv_nsec / 1e9)); |
584 (LREAL)broken_down_time->tm_sec + ((LREAL)IN.tv_nsec / 1e9)); |
787 } |
585 } |
788 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
586 if(res.len > STR_MAX_LEN) res.len = STR_MAX_LEN; |
789 return res; |
587 return res; |
790 } |
588 } |
791 /* BCD */ |
589 |
|
590 /**********************************************/ |
|
591 /* [ANY_DATE | TIME] _TO_ [ANY_DATE | TIME] */ |
|
592 /**********************************************/ |
|
593 |
|
594 static inline TOD __date_and_time_to_time_of_day(DT IN) {return (TOD){IN.tv_sec % 86400, IN.tv_nsec};} |
|
595 static inline DATE __date_and_time_to_date(DT IN){return (DATE){IN.tv_sec - (IN.tv_sec % (24*60*60)), 0};} |
|
596 |
|
597 /*****************/ |
|
598 /* FROM/TO BCD */ |
|
599 /*****************/ |
792 #define __bcd_digit(fac) |
600 #define __bcd_digit(fac) |
793 static inline ULINT __bcd_to_uint(EN_ENO_PARAMS, LWORD IN){ |
601 static inline ULINT __bcd_to_uint(LWORD IN){ |
794 ULINT res; |
602 ULINT res; |
795 ULINT i; |
603 ULINT i; |
796 TEST_EN(ULINT) |
|
797 |
604 |
798 res = IN & 0xf; |
605 res = IN & 0xf; |
799 for(i = 10ULL; i <= 1000000000000000ULL; i *= 10){ |
606 for(i = 10ULL; i <= 1000000000000000ULL; i *= 10){ |
800 if(!(IN >>= 4)) |
607 if(!(IN >>= 4)) |
801 break; |
608 break; |
802 res += (IN & 0xf) * i; |
609 res += (IN & 0xf) * i; |
803 } |
610 } |
804 return res; |
611 return res; |
805 } |
612 } |
806 |
613 |
807 static inline LWORD __uint_to_bcd(EN_ENO_PARAMS, ULINT IN){ |
614 static inline LWORD __uint_to_bcd(ULINT IN){ |
808 LWORD res; |
615 LWORD res; |
809 USINT i; |
616 USINT i; |
810 TEST_EN(LWORD) |
|
811 |
617 |
812 res = IN % 10; |
618 res = IN % 10; |
813 for(i = 4; i<=60; i += 4){ |
619 for(i = 4; i<=60; i += 4){ |
814 if(!(IN /= 10)) |
620 if(!(IN /= 10)) |
815 break; |
621 break; |
816 res |= (IN % 10) << i; |
622 res |= (IN % 10) << i; |
817 } |
623 } |
818 return res; |
624 return res; |
819 } |
625 } |
|
626 |
|
627 |
|
628 /************/ |
|
629 /* MOVE_* */ |
|
630 /************/ |
|
631 |
|
632 /* some helpful __move_[ANY] functions, used in the *_TO_** and MOVE standard functions */ |
|
633 /* e.g. __move_BOOL, __move_BYTE, __move_REAL, __move_TIME, ... */ |
|
634 #define __iec_(TYPENAME)\ |
|
635 static inline TYPENAME __move_##TYPENAME(TYPENAME op1) {return op1;} |
|
636 __ANY(__iec_) |
|
637 #undef __iec_ |
|
638 |
|
639 |
|
640 |
|
641 /*****************************************************************/ |
|
642 /*****************************************************************/ |
|
643 /***** *****/ |
|
644 /***** IEC 61131-3 *****/ |
|
645 /***** S T A N D A R D F U N C T I O N S *****/ |
|
646 /***** *****/ |
|
647 /*****************************************************************/ |
|
648 /*****************************************************************/ |
|
649 |
|
650 /* NOTE: If you want to know what all these strange macros are doing, |
|
651 * just parse this file through a C preprocessor, and analyse the output! |
|
652 * $gcc -E iec_std_lib.h |
|
653 */ |
|
654 |
|
655 /* NOTE: We only define and declare the explicitly typed standard functions |
|
656 * (e.g., SIN_REAL, SIN_LREAL, ..., ADD_SINT, ADD_INT, ADD_LINT, ...) |
|
657 * We do not declare/define the overloaded functions |
|
658 * (SIN, ADD, ...). |
|
659 * When handling a call to an overloaded function, the iec2c compiler |
|
660 * will determine in stage3 the data type of the parameter being passed, |
|
661 * and in stage4 generate the C code to call the correct |
|
662 * typed standard function. |
|
663 */ |
|
664 |
|
665 /* NOTE on explicit typing of: |
|
666 * - Table 25 - Standard bit shift functions |
|
667 * - Table 29 - Character string Functions |
|
668 * |
|
669 * In section 2.5.1.4 (Typing, overloading, and type conversion) of the IEC 61131-3 (version 2) |
|
670 * of the standard, it is stated: |
|
671 * "A standard function, [...] is said to be overloaded when it |
|
672 * can operate on input data elements of various types within a generic type designator as defined in |
|
673 * 2.3.2. For instance, an overloaded addition function on generic type ANY_NUM can operate on data |
|
674 * of types LREAL, REAL, DINT, INT, and SINT." |
|
675 * [...] |
|
676 * "When a function which normally represents an overloaded operator is to be typed, i.e., the types |
|
677 * of its inputs and outputs restricted to a particular elementary or derived data type as defined in |
|
678 * 2.3, this shall be done by appending an "underline" character followed by the required type, as |
|
679 * shown in table 21." |
|
680 * |
|
681 * However, this explanation (as well as the example in table 21) only refers to functions where the same |
|
682 * generic data type is used for the single input and the output parameter. |
|
683 * How can we create explicitly types functions when this is not the case? |
|
684 * It does not seem to be covered by the standard. |
|
685 * |
|
686 * For this reason, we do not define the LEN_SINT, LEN_INT, LEN_STRING, LEN_[ANY_INT], LEN_[ANY_STRING] functions... |
|
687 */ |
|
688 |
|
689 |
|
690 /********************/ |
|
691 /* EN/ENO PARAMS */ |
|
692 /********************/ |
|
693 |
|
694 #define EN_ENO_PARAMS BOOL EN, BOOL *ENO |
|
695 |
|
696 #define TEST_EN(TYPENAME)\ |
|
697 if (!EN) {\ |
|
698 if (ENO != NULL)\ |
|
699 *ENO = __BOOL_LITERAL(FALSE);\ |
|
700 return __INIT_##TYPENAME;\ |
|
701 }\ |
|
702 else if (ENO != NULL)\ |
|
703 *ENO = __BOOL_LITERAL(TRUE); |
|
704 |
|
705 #define TEST_EN_COND(TYPENAME, COND)\ |
|
706 if (!EN || (COND)) {\ |
|
707 if (ENO != NULL)\ |
|
708 *ENO = __BOOL_LITERAL(FALSE);\ |
|
709 return __INIT_##TYPENAME;\ |
|
710 }\ |
|
711 else if (ENO != NULL)\ |
|
712 *ENO = __BOOL_LITERAL(TRUE); |
|
713 |
|
714 |
|
715 |
|
716 /*****************************************/ |
|
717 /*****************************************/ |
|
718 /* 2.5.1.5.1 Type Conversion Functions */ |
|
719 /*****************************************/ |
|
720 /*****************************************/ |
|
721 |
|
722 #define __convert_type(from_TYPENAME,to_TYPENAME, oper) \ |
|
723 static inline to_TYPENAME from_TYPENAME##_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\ |
|
724 TEST_EN(to_TYPENAME)\ |
|
725 return (to_TYPENAME)oper(op);\ |
|
726 } |
|
727 |
|
728 |
|
729 #define __to_anynum_(from_TYPENAME) __ANY_NUM_1(__iec_,from_TYPENAME) |
|
730 #define __to_anyint_(from_TYPENAME) __ANY_INT_1(__iec_,from_TYPENAME) |
|
731 #define __to_anybit_(from_TYPENAME) __ANY_BIT_1(__iec_,from_TYPENAME) |
|
732 #define __to_anynbit_(from_TYPENAME) __ANY_NBIT_1(__iec_,from_TYPENAME) |
|
733 #define __to_anysint_(from_TYPENAME) __ANY_SINT_1(__iec_,from_TYPENAME) |
|
734 #define __to_anyuint_(from_TYPENAME) __ANY_UINT_1(__iec_,from_TYPENAME) |
|
735 #define __to_anyreal_(from_TYPENAME) __ANY_REAL_1(__iec_,from_TYPENAME) |
|
736 #define __to_anydate_(from_TYPENAME) __ANY_DATE_1(__iec_,from_TYPENAME) |
|
737 |
|
738 /******** [ANY_BIT]_TO_[ANY_NUM | ANT_BIT] ************/ |
|
739 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __move_##to_TYPENAME) |
|
740 __ANY_BIT(__to_anynum_) |
|
741 __ANY_BIT(__to_anybit_) |
|
742 #undef __iec_ |
|
743 |
|
744 /******** [ANY_INT]_TO_[ANY_NUM | ANT_BIT] ************/ |
|
745 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __move_##to_TYPENAME) |
|
746 __ANY_INT(__to_anynum_) |
|
747 __ANY_INT(__to_anybit_) |
|
748 #undef __iec_ |
|
749 |
|
750 /******** [ANY_REAL]_TO_[ANY_BIT] ************/ |
|
751 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __real_to_bit) |
|
752 __ANY_REAL(__to_anybit_) |
|
753 #undef __iec_ |
|
754 |
|
755 /******** [ANY_REAL]_TO_[ANY_INT] ************/ |
|
756 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __real_to_sint) |
|
757 __ANY_REAL(__to_anysint_) |
|
758 #undef __iec_ |
|
759 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __real_to_uint) |
|
760 __ANY_REAL(__to_anyuint_) |
|
761 #undef __iec_ |
|
762 |
|
763 /******** [ANY_REAL]_TO_[ANY_REAL] ************/ |
|
764 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __move_##to_TYPENAME) |
|
765 __ANY_REAL(__to_anyreal_) |
|
766 #undef __iec_ |
|
767 |
|
768 /******** [ANY_BIT | ANY_INT]_TO_[TIME | ANY_DATE] ************/ |
|
769 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, TIME, __int_to_time) |
|
770 __ANY_BIT(__iec_) |
|
771 __ANY_INT(__iec_) |
|
772 #undef __iec_ |
|
773 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __int_to_time) |
|
774 __ANY_BIT(__to_anydate_) |
|
775 __ANY_INT(__to_anydate_) |
|
776 #undef __iec_ |
|
777 |
|
778 /******** [ANY_REAL]_TO_[TIME | ANY_DATE] ************/ |
|
779 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, TIME, __real_to_time) |
|
780 __ANY_REAL(__iec_) |
|
781 #undef __iec_ |
|
782 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __real_to_time) |
|
783 __ANY_REAL(__to_anydate_) |
|
784 #undef __iec_ |
|
785 |
|
786 /******** [TIME | ANY_DATE]_TO_[ANY_BIT | ANY_INT] ************/ |
|
787 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __time_to_int) |
|
788 __to_anyint_(TIME) |
|
789 __to_anybit_(TIME) |
|
790 __ANY_DATE(__to_anyint_) |
|
791 __ANY_DATE(__to_anybit_) |
|
792 #undef __iec_ |
|
793 |
|
794 /******** [TIME | ANY_DATE]_TO_[ANY_REAL] ************/ |
|
795 #define __iec_(to_TYPENAME,from_TYPENAME) __convert_type(from_TYPENAME, to_TYPENAME, __time_to_real) |
|
796 __to_anyreal_(TIME) |
|
797 __ANY_DATE(__to_anyreal_) |
|
798 #undef __iec_ |
|
799 |
|
800 |
|
801 /******** [ANY_DATE]_TO_[ANY_DATE | TIME] ************/ |
|
802 /* Not supported: DT_TO_TIME */ |
|
803 __convert_type(DT, DATE, __date_and_time_to_date) |
|
804 __convert_type(DT, DT, __move_DT) |
|
805 __convert_type(DT, TOD, __date_and_time_to_time_of_day) |
|
806 /* Not supported: DATE_TO_TIME */ |
|
807 __convert_type(DATE, DATE, __move_DATE) |
|
808 /* Not supported: DATE_TO_DT */ |
|
809 /* Not supported: DATE_TO_TOD */ |
|
810 /* Not supported: TOD_TO_TIME */ |
|
811 /* Not supported: TOD_TO_DATE */ |
|
812 /* Not supported: TOD_TO_DT */ |
|
813 __convert_type(TOD, TOD, __move_TOD) |
|
814 |
|
815 |
|
816 /******** TIME_TO_[ANY_DATE] ************/ |
|
817 /* Not supported: TIME_TO_DATE */ |
|
818 /* Not supported: TIME_TO_DT */ |
|
819 /* Not supported: TIME_TO_TOD */ |
|
820 |
|
821 /******** TIME_TO_TIME ************/ |
|
822 __convert_type(TIME, TIME, __move_TIME) |
|
823 |
|
824 |
|
825 /******** [ANY_BIT]_TO_STRING ************/ |
|
826 __convert_type(BOOL, STRING, __bool_to_string) |
|
827 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, STRING, __bit_to_string) |
|
828 __ANY_NBIT(__iec_) |
|
829 #undef __iec_ |
|
830 |
|
831 /******** [ANY_INT]_TO_STRING ************/ |
|
832 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, STRING, __sint_to_string) |
|
833 __ANY_SINT(__iec_) |
|
834 #undef __iec_ |
|
835 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, STRING, __uint_to_string) |
|
836 __ANY_UINT(__iec_) |
|
837 #undef __iec_ |
|
838 |
|
839 /******** [ANY_REAL]_TO_STRING ************/ |
|
840 #define __iec_(from_TYPENAME) __convert_type(from_TYPENAME, STRING, __real_to_string) |
|
841 __ANY_REAL(__iec_) |
|
842 #undef __iec_ |
|
843 |
|
844 /******** [ANY_DATE]_TO_STRING ************/ |
|
845 __convert_type(DATE, STRING, __date_to_string) |
|
846 __convert_type(DT, STRING, __dt_to_string) |
|
847 __convert_type(TOD, STRING, __tod_to_string) |
|
848 |
|
849 /******** TIME_TO_STRING ************/ |
|
850 __convert_type(TIME, STRING, __time_to_string) |
|
851 |
|
852 |
|
853 /******** STRING_TO_[ANY_BIT] ************/ |
|
854 __convert_type(STRING, BOOL, __string_to_bool) |
|
855 #define __iec_(to_TYPENAME) __convert_type(STRING, to_TYPENAME, __string_to_bit) |
|
856 __ANY_NBIT(__iec_) |
|
857 #undef __iec_ |
|
858 |
|
859 /******** STRING_TO_[ANY_INT] ************/ |
|
860 #define __iec_(to_TYPENAME) __convert_type(STRING, to_TYPENAME, __string_to_sint) |
|
861 __ANY_SINT(__iec_) |
|
862 #undef __iec_ |
|
863 #define __iec_(to_TYPENAME) __convert_type(STRING, to_TYPENAME, __string_to_uint) |
|
864 __ANY_UINT(__iec_) |
|
865 #undef __iec_ |
|
866 |
|
867 /******** STRING_TO_[ANY_REAL] ************/ |
|
868 #define __iec_(to_TYPENAME) __convert_type(STRING, to_TYPENAME, __string_to_real) |
|
869 __ANY_REAL(__iec_) |
|
870 #undef __iec_ |
|
871 |
|
872 /******** STRING_TO_[ANY_DATE] ************/ |
|
873 #define __iec_(to_TYPENAME) __convert_type(STRING, to_TYPENAME, __string_to_time) |
|
874 __ANY_DATE(__iec_) |
|
875 #undef __iec_ |
|
876 |
|
877 /******** STRING_TO_TIME ************/ |
|
878 __convert_type(STRING, TIME, __string_to_time) |
|
879 |
|
880 |
|
881 /******** TRUNC ************/ |
|
882 #define __iec_(to_TYPENAME,from_TYPENAME) \ |
|
883 static inline to_TYPENAME TRUNC__##to_TYPENAME##__##from_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\ |
|
884 TEST_EN(to_TYPENAME)\ |
|
885 return (to_TYPENAME)__move_##to_TYPENAME(op);\ |
|
886 } |
|
887 __ANY_REAL(__to_anyint_) |
|
888 #undef __iec_ |
|
889 |
|
890 |
|
891 /******** _TO_BCD ************/ |
|
892 #define __iec_(to_TYPENAME,from_TYPENAME) \ |
|
893 static inline to_TYPENAME from_TYPENAME##_TO_BCD_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\ |
|
894 TEST_EN(to_TYPENAME)\ |
|
895 return (to_TYPENAME)__uint_to_bcd(op);\ |
|
896 } |
|
897 __ANY_UINT(__to_anynbit_) |
|
898 #undef __iec_ |
|
899 |
|
900 |
|
901 /******** BCD_TO_ ************/ |
|
902 #define __iec_(to_TYPENAME,from_TYPENAME) \ |
|
903 static inline to_TYPENAME from_TYPENAME##_BCD_TO_##to_TYPENAME(EN_ENO_PARAMS, from_TYPENAME op){\ |
|
904 TEST_EN(to_TYPENAME)\ |
|
905 return (to_TYPENAME)__bcd_to_uint(op);\ |
|
906 } |
|
907 __ANY_NBIT(__to_anyuint_) |
|
908 #undef __iec_ |
|
909 |
|
910 |
|
911 /***********************************/ |
|
912 /***********************************/ |
|
913 /* 2.5.1.5.2 Numerical Functions */ |
|
914 /***********************************/ |
|
915 /***********************************/ |
820 |
916 |
821 /* workaround for va-args limitation on shorter than int params */ |
917 /* workaround for va-args limitation on shorter than int params */ |
822 #define VA_ARGS_REAL LREAL |
918 #define VA_ARGS_REAL LREAL |
823 #define VA_ARGS_LREAL LREAL |
919 #define VA_ARGS_LREAL LREAL |
824 #define VA_ARGS_SINT DINT |
920 #define VA_ARGS_SINT DINT |
839 #define VA_ARGS_WSTRING WSTRING |
935 #define VA_ARGS_WSTRING WSTRING |
840 #define VA_ARGS_DATE DATE |
936 #define VA_ARGS_DATE DATE |
841 #define VA_ARGS_TOD TOD |
937 #define VA_ARGS_TOD TOD |
842 #define VA_ARGS_DT DT |
938 #define VA_ARGS_DT DT |
843 |
939 |
844 /*******************************************/ |
940 |
845 /* Arithmetic and bitwise functions */ |
941 #define __numeric(fname,TYPENAME, FUNC) \ |
846 /*******************************************/ |
942 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
943 TEST_EN(TYPENAME)\ |
|
944 return FUNC(op);\ |
|
945 } |
|
946 |
|
947 /******************************************************************/ |
|
948 /*** Table 23 - Standard functions of one numeric variable ***/ |
|
949 /******************************************************************/ |
|
950 |
|
951 /**************/ |
|
952 /* ABS */ |
|
953 /**************/ |
|
954 /* explicitly typed function */ |
|
955 #define __iec_(TYPENAME) \ |
|
956 static inline TYPENAME ABS_##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
957 TEST_EN(TYPENAME)\ |
|
958 if (op < 0)\ |
|
959 return -op;\ |
|
960 return op;\ |
|
961 } |
|
962 __ANY_REAL(__iec_) |
|
963 __ANY_SINT(__iec_) |
|
964 #undef __iec_ |
|
965 |
|
966 #define __iec_(TYPENAME) \ |
|
967 static inline TYPENAME ABS_##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
968 TEST_EN(TYPENAME)\ |
|
969 return op;\ |
|
970 } |
|
971 __ANY_UINT(__iec_) |
|
972 #undef __iec_ |
|
973 |
|
974 /* overloaded function */ |
|
975 #define __iec_(TYPENAME) \ |
|
976 static inline TYPENAME ABS__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
977 TEST_EN(TYPENAME)\ |
|
978 if (op < 0)\ |
|
979 return -op;\ |
|
980 return op;\ |
|
981 } |
|
982 __ANY_REAL(__iec_) |
|
983 __ANY_SINT(__iec_) |
|
984 #undef __iec_ |
|
985 |
|
986 #define __iec_(TYPENAME) \ |
|
987 static inline TYPENAME ABS__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
988 TEST_EN(TYPENAME)\ |
|
989 return op;\ |
|
990 } |
|
991 __ANY_UINT(__iec_) |
|
992 #undef __iec_ |
|
993 |
|
994 |
|
995 /**************/ |
|
996 /* SQRT */ |
|
997 /**************/ |
|
998 /* explicitly typed function */ |
|
999 #define __iec_(TYPENAME) \ |
|
1000 __numeric(SQRT_, TYPENAME, sqrt) /* explicitly typed function */\ |
|
1001 __numeric(SQRT__##TYPENAME##__, TYPENAME, sqrt) /* overloaded function */ |
|
1002 __ANY_REAL(__iec_) |
|
1003 #undef __iec_ |
|
1004 |
|
1005 /**************/ |
|
1006 /* LN */ |
|
1007 /**************/ |
|
1008 #define __iec_(TYPENAME) \ |
|
1009 __numeric(LN_, TYPENAME, log) /* explicitly typed function */\ |
|
1010 __numeric(LN__##TYPENAME##__, TYPENAME, log) /* overloaded function */ |
|
1011 __ANY_REAL(__iec_) |
|
1012 #undef __iec_ |
|
1013 |
|
1014 |
|
1015 /**************/ |
|
1016 /* LOG */ |
|
1017 /**************/ |
|
1018 #define __iec_(TYPENAME) \ |
|
1019 __numeric(LOG_, TYPENAME, log10) /* explicitly typed function */\ |
|
1020 __numeric(LOG__##TYPENAME##__, TYPENAME, log10) /* overloaded function */ |
|
1021 __ANY_REAL(__iec_) |
|
1022 #undef __iec_ |
|
1023 |
|
1024 /**************/ |
|
1025 /* EXP */ |
|
1026 /**************/ |
|
1027 #define __iec_(TYPENAME) \ |
|
1028 __numeric(EXP_, TYPENAME, exp) /* explicitly typed function */\ |
|
1029 __numeric(EXP__##TYPENAME##__, TYPENAME, exp) /* overloaded function */ |
|
1030 __ANY_REAL(__iec_) |
|
1031 #undef __iec_ |
|
1032 |
|
1033 |
|
1034 /**************/ |
|
1035 /* SIN */ |
|
1036 /**************/ |
|
1037 #define __iec_(TYPENAME) \ |
|
1038 __numeric(SIN_, TYPENAME, sin) /* explicitly typed function */\ |
|
1039 __numeric(SIN__##TYPENAME##__, TYPENAME, sin) /* overloaded function */ |
|
1040 __ANY_REAL(__iec_) |
|
1041 #undef __iec_ |
|
1042 |
|
1043 |
|
1044 /**************/ |
|
1045 /* COS */ |
|
1046 /**************/ |
|
1047 #define __iec_(TYPENAME) \ |
|
1048 __numeric(COS_, TYPENAME, cos) /* explicitly typed function */\ |
|
1049 __numeric(COS__##TYPENAME##__, TYPENAME, cos) /* overloaded function */ |
|
1050 __ANY_REAL(__iec_) |
|
1051 #undef __iec_ |
|
1052 |
|
1053 /**************/ |
|
1054 /* TAN */ |
|
1055 /**************/ |
|
1056 #define __iec_(TYPENAME) \ |
|
1057 __numeric(TAN_, TYPENAME, tan) /* explicitly typed function */\ |
|
1058 __numeric(TAN__##TYPENAME##__, TYPENAME, tan) /* overloaded function */ |
|
1059 __ANY_REAL(__iec_) |
|
1060 #undef __iec_ |
|
1061 |
|
1062 |
|
1063 /**************/ |
|
1064 /* ASIN */ |
|
1065 /**************/ |
|
1066 #define __iec_(TYPENAME) \ |
|
1067 __numeric(ASIN_, TYPENAME, asin) /* explicitly typed function */\ |
|
1068 __numeric(ASIN__##TYPENAME##__, TYPENAME, asin) /* overloaded function */ |
|
1069 __ANY_REAL(__iec_) |
|
1070 #undef __iec_ |
|
1071 |
|
1072 /**************/ |
|
1073 /* ACOS */ |
|
1074 /**************/ |
|
1075 #define __iec_(TYPENAME) \ |
|
1076 __numeric(ACOS_, TYPENAME, acos) /* explicitly typed function */\ |
|
1077 __numeric(ACOS__##TYPENAME##__, TYPENAME, acos) /* overloaded function */ |
|
1078 __ANY_REAL(__iec_) |
|
1079 #undef __iec_ |
|
1080 |
|
1081 /**************/ |
|
1082 /* ATAN */ |
|
1083 /**************/ |
|
1084 #define __iec_(TYPENAME) \ |
|
1085 __numeric(ATAN_, TYPENAME, atan) /* explicitly typed function */\ |
|
1086 __numeric(ATAN__##TYPENAME##__, TYPENAME, atan) /* overloaded function */ |
|
1087 __ANY_REAL(__iec_) |
|
1088 #undef __iec_ |
|
1089 |
|
1090 |
|
1091 |
|
1092 /*****************************************************/ |
|
1093 /*** Table 24 - Standard arithmetic functions ***/ |
|
1094 /*****************************************************/ |
|
1095 /* |
|
1096 Unfortunately, the following does not work!! |
|
1097 |
|
1098 #define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int)) |
|
1099 |
847 #define __arith_expand(fname,TYPENAME, OP) \ |
1100 #define __arith_expand(fname,TYPENAME, OP) \ |
848 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
1101 #define fname(EN, ENO, ...) fname__(EN, ENO, NUMARGS(__VA_ARGS__), __VA_ARGS__)\ |
|
1102 static inline TYPENAME fname__(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
|
1103 va_list ap;\ |
|
1104 UINT i;\ |
|
1105 TEST_EN(TYPENAME)\ |
|
1106 \ |
|
1107 va_start (ap, op1); \ |
|
1108 \ |
|
1109 for (i = 0; i < param_count - 1; i++){\ |
|
1110 op1 = op1 OP va_arg (ap, VA_ARGS_##TYPENAME);\ |
|
1111 }\ |
|
1112 \ |
|
1113 va_end (ap); \ |
|
1114 return op1;\ |
|
1115 } |
|
1116 */ |
|
1117 |
|
1118 |
|
1119 #define __arith_expand(fname,TYPENAME, OP) \ |
|
1120 static inline TYPENAME fname(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
849 va_list ap;\ |
1121 va_list ap;\ |
850 UINT i;\ |
1122 UINT i;\ |
851 TEST_EN(TYPENAME)\ |
1123 TEST_EN(TYPENAME)\ |
852 \ |
1124 \ |
853 va_start (ap, op1); /* Initialize the argument list. */\ |
1125 va_start (ap, op1); /* Initialize the argument list. */\ |
859 va_end (ap); /* Clean up. */\ |
1131 va_end (ap); /* Clean up. */\ |
860 return op1;\ |
1132 return op1;\ |
861 } |
1133 } |
862 |
1134 |
863 #define __arith_static(fname,TYPENAME, OP) \ |
1135 #define __arith_static(fname,TYPENAME, OP) \ |
864 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\ |
1136 static inline TYPENAME fname(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\ |
865 TEST_EN(TYPENAME)\ |
1137 TEST_EN(TYPENAME)\ |
866 return op1 OP op2;\ |
1138 return op1 OP op2;\ |
867 } |
1139 } |
868 |
1140 |
869 /**************/ |
1141 /**************/ |
870 /* ADD */ |
1142 /* ADD */ |
871 /**************/ |
1143 /**************/ |
872 #define __add_(TYPENAME) __arith_expand(__add_, TYPENAME, + ) |
1144 #define __iec_(TYPENAME) \ |
873 ANY_NUM(__add_) |
1145 __arith_expand(ADD_##TYPENAME, TYPENAME, +) /* explicitly typed function */\ |
874 |
1146 __arith_expand(ADD__##TYPENAME##__##TYPENAME, TYPENAME, +) /* overloaded function */ |
875 /**************/ |
1147 __ANY_NUM(__iec_) |
876 /* MUL */ |
1148 #undef __iec_ |
877 /**************/ |
1149 |
878 #define __mul_(TYPENAME) __arith_expand(__mul_, TYPENAME, * ) |
1150 /**************/ |
879 ANY_NUM(__mul_) |
1151 /* MUL */ |
880 |
1152 /**************/ |
881 /**************/ |
1153 #define __iec_(TYPENAME) \ |
882 /* SUB */ |
1154 __arith_expand(MUL_##TYPENAME, TYPENAME, *) /* explicitly typed function */\ |
883 /**************/ |
1155 __arith_expand(MUL__##TYPENAME##__##TYPENAME, TYPENAME, *) /* overloaded function */ |
884 #define __sub_(TYPENAME) __arith_static(__sub_, TYPENAME, - ) |
1156 __ANY_NUM(__iec_) |
885 ANY_NUM(__sub_) |
1157 #undef __iec_ |
886 |
1158 |
887 /**************/ |
1159 /**************/ |
888 /* DIV */ |
1160 /* SUB */ |
889 /**************/ |
1161 /**************/ |
890 #define __div_(TYPENAME)\ |
1162 #define __iec_(TYPENAME) \ |
891 static inline TYPENAME __div_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\ |
1163 __arith_expand(SUB_##TYPENAME, TYPENAME, -) /* explicitly typed function */\ |
|
1164 __arith_expand(SUB__##TYPENAME##__##TYPENAME##__##TYPENAME, TYPENAME, -) /* overloaded function */ |
|
1165 __ANY_NUM(__iec_) |
|
1166 #undef __iec_ |
|
1167 |
|
1168 /**************/ |
|
1169 /* DIV */ |
|
1170 /**************/ |
|
1171 /* The explicitly typed standard functions */ |
|
1172 #define __iec_(TYPENAME)\ |
|
1173 static inline TYPENAME DIV_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\ |
892 TEST_EN_COND(TYPENAME, op2 == 0)\ |
1174 TEST_EN_COND(TYPENAME, op2 == 0)\ |
893 return op1 / op2;\ |
1175 return op1 / op2;\ |
894 } |
1176 } |
895 ANY_NUM(__div_) |
1177 __ANY_NUM(__iec_) |
896 |
1178 #undef __iec_ |
897 /**************/ |
1179 |
898 /* MOD */ |
1180 /* The overloaded standard functions */ |
899 /**************/ |
1181 #define __iec_(TYPENAME)\ |
900 #define __mod_(TYPENAME) __arith_static(__mod_, TYPENAME, % ) |
1182 static inline TYPENAME DIV__##TYPENAME##__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME op1, TYPENAME op2){\ |
901 ANY_INT(__mod_) |
1183 TEST_EN_COND(TYPENAME, op2 == 0)\ |
902 |
1184 return op1 / op2;\ |
903 /**************/ |
1185 } |
904 /* AND */ |
1186 __ANY_NUM(__iec_) |
905 /**************/ |
1187 #undef __iec_ |
906 __arith_expand(__and_, BOOL, && ) |
1188 |
907 #define __and_(TYPENAME) __arith_expand(__and_, TYPENAME, & ) |
1189 /**************/ |
908 ANY_NBIT(__and_) |
1190 /* MOD */ |
909 |
1191 /**************/ |
910 /*************/ |
1192 /* The explicitly typed standard functions */ |
911 /* OR */ |
1193 #define __iec_(TYPENAME)\ |
912 /*************/ |
1194 __arith_expand(MOD_##TYPENAME, TYPENAME, %) /* explicitly typed function */\ |
913 __arith_expand(__or_, BOOL, || ) |
1195 __arith_expand(MOD__##TYPENAME##__##TYPENAME##__##TYPENAME, TYPENAME, %) /* overloaded function */ |
914 #define __or_(TYPENAME) __arith_expand(__or_, TYPENAME, |) |
1196 __ANY_INT(__iec_) |
915 ANY_NBIT(__or_) |
1197 #undef __iec_ |
916 |
1198 |
917 /**************/ |
1199 /**************/ |
918 /* XOR */ |
1200 /* EXPT */ |
919 /**************/ |
1201 /**************/ |
920 static inline BOOL __xor_BOOL(EN_ENO_PARAMS, UINT param_count, BOOL op1, ...){ |
1202 /* overloaded function */ |
921 va_list ap; |
1203 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
922 UINT i; |
1204 static inline in1_TYPENAME EXPT__##in1_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME\ |
923 TEST_EN(BOOL) |
1205 (EN_ENO_PARAMS, in1_TYPENAME IN1, in2_TYPENAME IN2){\ |
924 |
1206 TEST_EN(in1_TYPENAME)\ |
925 va_start (ap, op1); /* Initialize the argument list. */ |
1207 return pow(IN1, IN2);\ |
926 |
1208 } |
927 for (i = 0; i < param_count - 1; i++){ |
1209 #define __in1_anyreal_(in2_TYPENAME) __ANY_REAL_1(__iec_,in2_TYPENAME) |
928 BOOL tmp = va_arg (ap, VA_ARGS_BOOL); |
1210 __ANY_NUM(__in1_anyreal_) |
929 op1 = (op1 && !tmp) || (!op1 && tmp); |
1211 #undef __iec_ |
930 } |
1212 |
931 |
1213 |
932 va_end (ap); /* Clean up. */ |
1214 |
933 return op1; |
1215 /***************/ |
934 } |
1216 /* MOVE */ |
935 #define __xor_(TYPENAME) __arith_expand(__xor_, TYPENAME, ^) |
1217 /***************/ |
936 ANY_NBIT(__xor_) |
1218 /* The explicitly typed standard functions */ |
937 |
1219 #define __iec_(TYPENAME)\ |
938 /**************/ |
1220 static inline TYPENAME MOVE_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
939 /* NOT */ |
1221 TEST_EN(TYPENAME)\ |
940 /**************/ |
1222 return op1;\ |
941 static inline BOOL __not_BOOL(EN_ENO_PARAMS, BOOL op1){ |
1223 } |
|
1224 __ANY(__iec_) |
|
1225 #undef __iec_ |
|
1226 |
|
1227 /* Overloaded function */ |
|
1228 #define __iec_(TYPENAME)\ |
|
1229 static inline TYPENAME MOVE__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
|
1230 TEST_EN(TYPENAME)\ |
|
1231 return op1;\ |
|
1232 } |
|
1233 __ANY(__iec_) |
|
1234 #undef __iec_ |
|
1235 |
|
1236 |
|
1237 |
|
1238 |
|
1239 |
|
1240 |
|
1241 /***********************************/ |
|
1242 /***********************************/ |
|
1243 /* 2.5.1.5.3 Bit String Functions */ |
|
1244 /***********************************/ |
|
1245 /***********************************/ |
|
1246 |
|
1247 /****************************************************/ |
|
1248 /*** Table 25 - Standard bit shift functions ***/ |
|
1249 /****************************************************/ |
|
1250 |
|
1251 /* We do not delcare explcitly typed versions of the functions in table 25. |
|
1252 * See note above regarding explicitly typed functions for more details. |
|
1253 */ |
|
1254 #define __in1_anynbit_(in2_TYPENAME) __ANY_NBIT_1(__iec_,in2_TYPENAME) |
|
1255 |
|
1256 #define __shift_(fname, in1_TYPENAME, in2_TYPENAME, OP)\ |
|
1257 static inline in1_TYPENAME fname(EN_ENO_PARAMS, in1_TYPENAME IN, in2_TYPENAME N) {\ |
|
1258 TEST_EN(in1_TYPENAME)\ |
|
1259 return IN OP N;\ |
|
1260 } |
|
1261 |
|
1262 /**************/ |
|
1263 /* SHL */ |
|
1264 /**************/ |
|
1265 #define __iec_(TYPENAME) \ |
|
1266 /* Overloaded function */\ |
|
1267 static inline BOOL SHL__BOOL__##TYPENAME(EN_ENO_PARAMS, BOOL IN, TYPENAME N) { \ |
|
1268 TEST_EN(BOOL);\ |
|
1269 return (N==0)? IN : __INIT_BOOL; /* shifting by N>1 will always introduce a 0 */\ |
|
1270 } |
|
1271 __ANY_INT(__iec_) |
|
1272 #undef __iec_ |
|
1273 |
|
1274 |
|
1275 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
|
1276 __shift_(SHL__##in1_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME, in1_TYPENAME, in2_TYPENAME, << )/* Overloaded function */ |
|
1277 __ANY_INT(__in1_anynbit_) |
|
1278 #undef __iec_ |
|
1279 |
|
1280 |
|
1281 /**************/ |
|
1282 /* SHR */ |
|
1283 /**************/ |
|
1284 #define __iec_(TYPENAME) \ |
|
1285 /* Overloaded function */\ |
|
1286 static inline BOOL SHR__BOOL__##TYPENAME(EN_ENO_PARAMS, BOOL IN, TYPENAME N) { \ |
|
1287 TEST_EN(BOOL);\ |
|
1288 return (N==0)? IN : __INIT_BOOL; /* shifting by N>1 will always introduce a 0 */\ |
|
1289 } |
|
1290 __ANY_INT(__iec_) |
|
1291 #undef __iec_ |
|
1292 |
|
1293 |
|
1294 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
|
1295 __shift_(SHR__##in1_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME, in1_TYPENAME, in2_TYPENAME, >> )/* Overloaded function */ |
|
1296 __ANY_INT(__in1_anynbit_) |
|
1297 #undef __iec_ |
|
1298 |
|
1299 |
|
1300 /**************/ |
|
1301 /* ROR */ |
|
1302 /**************/ |
|
1303 #define __iec_(TYPENAME) \ |
|
1304 /* Overloaded function */\ |
|
1305 static inline BOOL ROR__BOOL__##TYPENAME(EN_ENO_PARAMS, BOOL IN, TYPENAME N) { \ |
|
1306 TEST_EN(BOOL);\ |
|
1307 return IN; /* rotating a single bit by any value N will not change that bit! */\ |
|
1308 } |
|
1309 __ANY_INT(__iec_) |
|
1310 #undef __iec_ |
|
1311 |
|
1312 |
|
1313 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
|
1314 static inline in1_TYPENAME ROR__##in1_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME(EN_ENO_PARAMS, in1_TYPENAME IN, in2_TYPENAME N){\ |
|
1315 TEST_EN(in1_TYPENAME)\ |
|
1316 N %= 8*sizeof(in1_TYPENAME);\ |
|
1317 return (IN >> N) | (IN << (8*sizeof(in1_TYPENAME)-N));\ |
|
1318 } |
|
1319 __ANY_INT(__in1_anynbit_) |
|
1320 #undef __iec_ |
|
1321 |
|
1322 |
|
1323 /**************/ |
|
1324 /* ROL */ |
|
1325 /**************/ |
|
1326 #define __iec_(TYPENAME) \ |
|
1327 /* Overloaded function */\ |
|
1328 static inline BOOL ROL__BOOL__##TYPENAME(EN_ENO_PARAMS, BOOL IN, TYPENAME N) { \ |
|
1329 TEST_EN(BOOL);\ |
|
1330 return IN; /* rotating a single bit by any value N will not change that bit! */\ |
|
1331 } |
|
1332 __ANY_INT(__iec_) |
|
1333 #undef __iec_ |
|
1334 |
|
1335 |
|
1336 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
|
1337 static inline in1_TYPENAME ROL__##in1_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME(EN_ENO_PARAMS, in1_TYPENAME IN, in2_TYPENAME N){\ |
|
1338 TEST_EN(in1_TYPENAME)\ |
|
1339 N %= 8*sizeof(in1_TYPENAME);\ |
|
1340 return (IN << N) | (IN >> (8*sizeof(in1_TYPENAME)-N));\ |
|
1341 } |
|
1342 __ANY_INT(__in1_anynbit_) |
|
1343 #undef __iec_ |
|
1344 |
|
1345 |
|
1346 |
|
1347 /*********************/ |
|
1348 /*** Table 26 ***/ |
|
1349 /*********************/ |
|
1350 |
|
1351 /**************/ |
|
1352 /* AND */ |
|
1353 /**************/ |
|
1354 __arith_expand(AND_BOOL, BOOL, && ) /* The explicitly typed standard functions */ |
|
1355 __arith_expand(AND__BOOL__BOOL, BOOL, && ) /* Overloaded function */ |
|
1356 |
|
1357 #define __iec_(TYPENAME) \ |
|
1358 __arith_expand(AND_##TYPENAME, TYPENAME, &) /* The explicitly typed standard functions */\ |
|
1359 __arith_expand(AND__##TYPENAME##__##TYPENAME, TYPENAME, &) /* Overloaded function */ |
|
1360 __ANY_NBIT(__iec_) |
|
1361 #undef __iec_ |
|
1362 |
|
1363 /*************/ |
|
1364 /* OR */ |
|
1365 /*************/ |
|
1366 __arith_expand(OR_BOOL, BOOL, || ) /* The explicitly typed standard functions */ |
|
1367 __arith_expand(OR__BOOL__BOOL, BOOL, || ) /* Overloaded function */ |
|
1368 |
|
1369 #define __iec_(TYPENAME) \ |
|
1370 __arith_expand(OR_##TYPENAME, TYPENAME, |) /* The explicitly typed standard functions */\ |
|
1371 __arith_expand(OR__##TYPENAME##__##TYPENAME, TYPENAME, |) /* Overloaded function */ |
|
1372 __ANY_NBIT(__iec_) |
|
1373 #undef __iec_ |
|
1374 |
|
1375 /**************/ |
|
1376 /* XOR */ |
|
1377 /**************/ |
|
1378 #define __xorbool_expand(fname) \ |
|
1379 static inline BOOL fname(EN_ENO_PARAMS, UINT param_count, BOOL op1, ...){ \ |
|
1380 va_list ap; \ |
|
1381 UINT i; \ |
|
1382 TEST_EN(BOOL) \ |
|
1383 \ |
|
1384 va_start (ap, op1); /* Initialize the argument list. */ \ |
|
1385 \ |
|
1386 for (i = 0; i < param_count - 1; i++){ \ |
|
1387 BOOL tmp = va_arg (ap, VA_ARGS_BOOL); \ |
|
1388 op1 = (op1 && !tmp) || (!op1 && tmp); \ |
|
1389 } \ |
|
1390 \ |
|
1391 va_end (ap); /* Clean up. */ \ |
|
1392 return op1; \ |
|
1393 } |
|
1394 |
|
1395 __xorbool_expand(XOR_BOOL) /* The explicitly typed standard functions */ |
|
1396 __xorbool_expand(XOR__BOOL__BOOL) /* Overloaded function */ |
|
1397 |
|
1398 #define __iec_(TYPENAME) \ |
|
1399 __arith_expand(XOR_##TYPENAME, TYPENAME, ^) /* The explicitly typed standard functions */\ |
|
1400 __arith_expand(XOR__##TYPENAME##__##TYPENAME, TYPENAME, ^) /* Overloaded function */\ |
|
1401 __ANY_NBIT(__iec_) |
|
1402 #undef __iec_ |
|
1403 |
|
1404 |
|
1405 /**************/ |
|
1406 /* NOT */ |
|
1407 /**************/ |
|
1408 /* The explicitly typed standard functions */ |
|
1409 static inline BOOL NOT_BOOL(EN_ENO_PARAMS, BOOL op1){ |
942 TEST_EN(BOOL) |
1410 TEST_EN(BOOL) |
943 return !op1; |
1411 return !op1; |
944 } |
1412 } |
945 |
1413 |
946 #define __not_(TYPENAME)\ |
1414 /* Overloaded function */ |
947 static inline TYPENAME __not_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
1415 static inline BOOL NOT__BOOL__BOOL(EN_ENO_PARAMS, BOOL op1){ |
|
1416 TEST_EN(BOOL) |
|
1417 return !op1; |
|
1418 } |
|
1419 |
|
1420 /* The explicitly typed standard functions */ |
|
1421 #define __iec_(TYPENAME)\ |
|
1422 static inline TYPENAME NOT_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
948 TEST_EN(TYPENAME)\ |
1423 TEST_EN(TYPENAME)\ |
949 return ~op1;\ |
1424 return ~op1;\ |
950 } |
1425 } |
951 ANY_NBIT(__not_) |
1426 __ANY_NBIT(__iec_) |
952 |
1427 #undef __iec_ |
953 /***************/ |
1428 |
954 /* MOVE */ |
1429 /* Overloaded function */ |
955 /***************/ |
1430 #define __iec_(TYPENAME)\ |
956 #define __move_(TYPENAME)\ |
1431 static inline TYPENAME NOT__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
957 static inline TYPENAME __move_##TYPENAME(EN_ENO_PARAMS, TYPENAME op1){\ |
|
958 TEST_EN(TYPENAME)\ |
1432 TEST_EN(TYPENAME)\ |
959 return op1;\ |
1433 return ~op1;\ |
960 } |
1434 } |
961 ANY(__move_) |
1435 __ANY_NBIT(__iec_) |
962 |
1436 #undef __iec_ |
963 /**************/ |
1437 |
964 /* Binary ops */ |
1438 |
965 /**************/ |
1439 |
966 #define __shift_(fname, TYPENAME, OP)\ |
1440 |
967 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, TYPENAME IN, USINT N) {\ |
1441 |
968 TEST_EN(TYPENAME)\ |
1442 |
969 return IN OP N;\ |
1443 /***************************************************/ |
970 } |
1444 /***************************************************/ |
971 |
1445 /* 2.5.1.5.4 Selection and comparison Functions */ |
972 #define __shl_(TYPENAME) __shift_(__shl_, TYPENAME, << ) |
1446 /***************************************************/ |
973 /* Call previously defined macro for each ANY_NBIT */ |
1447 /***************************************************/ |
974 ANY_NBIT(__shl_) |
1448 |
975 |
1449 /*********************/ |
976 #define __shr_(TYPENAME) __shift_(__shr_, TYPENAME, >> ) |
1450 /*** Table 27 ***/ |
977 /* Call previously defined macro for each ANY_NBIT */ |
1451 /*********************/ |
978 ANY_NBIT(__shr_) |
1452 |
979 |
1453 |
980 #define __ror_(TYPENAME)\ |
1454 /**************/ |
981 static inline TYPENAME __ror_##TYPENAME(EN_ENO_PARAMS, TYPENAME IN, USINT N){\ |
1455 /* SEL */ |
982 TEST_EN(TYPENAME)\ |
1456 /**************/ |
983 N %= 8*sizeof(TYPENAME);\ |
1457 |
984 return (IN >> N) | (IN << (8*sizeof(TYPENAME)-N));\ |
1458 /* The explicitly typed standard functions */ |
985 } |
1459 #define __iec_(TYPENAME)\ |
986 /* Call previously defined macro for each ANY_NBIT */ |
1460 static inline TYPENAME SEL_##TYPENAME(EN_ENO_PARAMS, BOOL G, TYPENAME op0, TYPENAME op1){\ |
987 ANY_NBIT(__ror_) |
|
988 |
|
989 #define __rol_(TYPENAME)\ |
|
990 static inline TYPENAME __rol_##TYPENAME(EN_ENO_PARAMS, TYPENAME IN, USINT N){\ |
|
991 TEST_EN(TYPENAME)\ |
|
992 N %= 8*sizeof(TYPENAME);\ |
|
993 return (IN << N) | (IN >> (8*sizeof(TYPENAME)-N));\ |
|
994 } |
|
995 /* Call previously defined macro for each ANY_NBIT */ |
|
996 ANY_NBIT(__rol_) |
|
997 |
|
998 /*******************************************/ |
|
999 /* Arithmetic and bitwise functions */ |
|
1000 /*******************************************/ |
|
1001 |
|
1002 #define __numeric(fname,TYPENAME, FUNC) \ |
|
1003 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
1004 TEST_EN(TYPENAME)\ |
|
1005 return FUNC(op);\ |
|
1006 } |
|
1007 |
|
1008 /**************/ |
|
1009 /* ABS */ |
|
1010 /**************/ |
|
1011 #define __abs_signed(TYPENAME) \ |
|
1012 static inline TYPENAME __abs_##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
1013 TEST_EN(TYPENAME)\ |
|
1014 if (op < 0)\ |
|
1015 return -op;\ |
|
1016 return op;\ |
|
1017 } |
|
1018 ANY_REAL(__abs_signed) |
|
1019 ANY_SINT(__abs_signed) |
|
1020 |
|
1021 #define __abs_unsigned(TYPENAME) \ |
|
1022 static inline TYPENAME __abs_##TYPENAME(EN_ENO_PARAMS, TYPENAME op){\ |
|
1023 TEST_EN(TYPENAME)\ |
|
1024 return op;\ |
|
1025 } |
|
1026 ANY_UINT(__abs_unsigned) |
|
1027 |
|
1028 /**************/ |
|
1029 /* SQRT */ |
|
1030 /**************/ |
|
1031 #define __sqrt_(TYPENAME) __numeric(__sqrt_, TYPENAME, sqrt) |
|
1032 ANY_REAL(__sqrt_) |
|
1033 |
|
1034 /**************/ |
|
1035 /* LN */ |
|
1036 /**************/ |
|
1037 #define __ln_(TYPENAME) __numeric(__ln_, TYPENAME, log) |
|
1038 ANY_REAL(__ln_) |
|
1039 |
|
1040 /**************/ |
|
1041 /* LOG */ |
|
1042 /**************/ |
|
1043 #define __log_(TYPENAME) __numeric(__log_, TYPENAME, log10) |
|
1044 ANY_REAL(__log_) |
|
1045 |
|
1046 /**************/ |
|
1047 /* EXP */ |
|
1048 /**************/ |
|
1049 #define __exp_(TYPENAME) __numeric(__exp_, TYPENAME, exp) |
|
1050 ANY_REAL(__exp_) |
|
1051 |
|
1052 /**************/ |
|
1053 /* SIN */ |
|
1054 /**************/ |
|
1055 #define __sin_(TYPENAME) __numeric(__sin_, TYPENAME, sin) |
|
1056 ANY_REAL(__sin_) |
|
1057 |
|
1058 /**************/ |
|
1059 /* COS */ |
|
1060 /**************/ |
|
1061 #define __cos_(TYPENAME) __numeric(__cos_, TYPENAME, cos) |
|
1062 ANY_REAL(__cos_) |
|
1063 |
|
1064 /**************/ |
|
1065 /* TAN */ |
|
1066 /**************/ |
|
1067 #define __tan_(TYPENAME) __numeric(__tan_, TYPENAME, tan) |
|
1068 ANY_REAL(__tan_) |
|
1069 |
|
1070 /**************/ |
|
1071 /* ASIN */ |
|
1072 /**************/ |
|
1073 #define __asin_(TYPENAME) __numeric(__asin_, TYPENAME, asin) |
|
1074 ANY_REAL(__asin_) |
|
1075 |
|
1076 /**************/ |
|
1077 /* ACOS */ |
|
1078 /**************/ |
|
1079 #define __acos_(TYPENAME) __numeric(__acos_, TYPENAME, acos) |
|
1080 ANY_REAL(__acos_) |
|
1081 |
|
1082 /**************/ |
|
1083 /* ATAN */ |
|
1084 /**************/ |
|
1085 #define __atan_(TYPENAME) __numeric(__atan_, TYPENAME, atan) |
|
1086 ANY_REAL(__atan_) |
|
1087 |
|
1088 /**************/ |
|
1089 /* EXPT */ |
|
1090 /**************/ |
|
1091 #define __expt_(TYPENAME)\ |
|
1092 static inline TYPENAME __expt_##TYPENAME(EN_ENO_PARAMS, TYPENAME IN1, REAL IN2){\ |
|
1093 TEST_EN(TYPENAME)\ |
|
1094 return pow(IN1, IN2);\ |
|
1095 }ANY_REAL(__expt_) |
|
1096 |
|
1097 /**************/ |
|
1098 /* Selection */ |
|
1099 /**************/ |
|
1100 |
|
1101 /**************/ |
|
1102 /* SEL */ |
|
1103 /**************/ |
|
1104 |
|
1105 #define __sel_(TYPENAME)\ |
|
1106 static inline TYPENAME __sel_##TYPENAME(EN_ENO_PARAMS, BOOL G, TYPENAME op0, TYPENAME op1){\ |
|
1107 TEST_EN(TYPENAME)\ |
1461 TEST_EN(TYPENAME)\ |
1108 return G ? op1 : op0;\ |
1462 return G ? op1 : op0;\ |
1109 } |
1463 } |
1110 ANY(__sel_) |
1464 __ANY(__iec_) |
1111 |
1465 #undef __iec_ |
1112 /**************/ |
1466 |
1113 /* limit */ |
1467 /* Overloaded function */ |
1114 /**************/ |
1468 #define __iec_(TYPENAME)\ |
1115 |
1469 static inline TYPENAME SEL__##TYPENAME##__BOOL__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, BOOL G, TYPENAME op0, TYPENAME op1){\ |
1116 #define __limit_(TYPENAME)\ |
|
1117 static inline TYPENAME __limit_##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1118 TEST_EN(TYPENAME)\ |
1470 TEST_EN(TYPENAME)\ |
1119 return IN > MN ? IN < MX ? IN : MX : MN;\ |
1471 return G ? op1 : op0;\ |
1120 } |
1472 } |
1121 |
1473 __ANY(__iec_) |
1122 /* Call previously defined macro for each concerned type */ |
1474 #undef __iec_ |
1123 ANY_NBIT(__limit_) |
1475 |
1124 ANY_NUM(__limit_) |
|
1125 |
|
1126 #define __limit_time(TYPENAME)\ |
|
1127 static inline TYPENAME __limit_##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1128 TEST_EN(TYPENAME)\ |
|
1129 return __TIME_CMP(IN, MN) > 0 ? /* IN>MN ?*/\ |
|
1130 __TIME_CMP(IN, MX) < 0 ? /* IN<MX ?*/\ |
|
1131 IN : MX : MN;\ |
|
1132 } |
|
1133 |
|
1134 /* Call previously defined macro for each concerned type */ |
|
1135 ANY_DATE(__limit_time) |
|
1136 __limit_time(TIME) |
|
1137 |
|
1138 static inline STRING __limit_STRING(EN_ENO_PARAMS, STRING MN, STRING IN, STRING MX){ |
|
1139 TEST_EN(STRING) |
|
1140 return __STR_CMP(IN, MN) > 0 ? __STR_CMP(IN, MX) < 0 ? IN : MX : MN; |
|
1141 } |
|
1142 |
1476 |
1143 /**************/ |
1477 /**************/ |
1144 /* MAX */ |
1478 /* MAX */ |
1145 /**************/ |
1479 /**************/ |
1146 |
1480 |
1147 #define __extrem_(fname,TYPENAME, COND) \ |
1481 #define __extrem_(fname,TYPENAME, COND) \ |
1148 static inline TYPENAME fname##TYPENAME(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
1482 static inline TYPENAME fname(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
1149 va_list ap;\ |
1483 va_list ap;\ |
1150 UINT i;\ |
1484 UINT i;\ |
1151 TEST_EN(TYPENAME)\ |
1485 TEST_EN(TYPENAME)\ |
1152 \ |
1486 \ |
1153 va_start (ap, op1); /* Initialize the argument list. */\ |
1487 va_start (ap, op1); /* Initialize the argument list. */\ |
1159 \ |
1493 \ |
1160 va_end (ap); /* Clean up. */\ |
1494 va_end (ap); /* Clean up. */\ |
1161 return op1;\ |
1495 return op1;\ |
1162 } |
1496 } |
1163 |
1497 |
1164 #define __max_num(TYPENAME) __extrem_(__max_,TYPENAME, op1 < tmp) |
1498 /* Max for numerical data types */ |
1165 ANY_NBIT(__max_num) |
1499 #define __iec_(TYPENAME) \ |
1166 ANY_NUM(__max_num) |
1500 __extrem_(MAX_##TYPENAME,TYPENAME, op1 < tmp) /* The explicitly typed standard functions */\ |
1167 |
1501 __extrem_(MAX__##TYPENAME##__##TYPENAME,TYPENAME, op1 < tmp) /* Overloaded function */ |
1168 __extrem_(__max_, STRING, __STR_CMP(op1,tmp) < 0) |
1502 __ANY_BIT(__iec_) |
1169 #define __max_time(TYPENAME) __extrem_(__max_, TYPENAME, __TIME_CMP(op1, tmp) < 0) |
1503 __ANY_NUM(__iec_) |
1170 |
1504 #undef __iec_ |
1171 /* Call previously defined macro for each concerned type */ |
1505 |
1172 ANY_DATE(__max_time) |
1506 /* Max for time data types */ |
1173 __max_time(TIME) |
1507 #define __iec_(TYPENAME) \ |
|
1508 __extrem_(MAX_##TYPENAME, TYPENAME, __time_cmp(op1, tmp) < 0) /* The explicitly typed standard functions */\ |
|
1509 __extrem_(MAX__##TYPENAME##__##TYPENAME, TYPENAME, __time_cmp(op1, tmp) < 0) /* Overloaded function */ |
|
1510 __ANY_DATE(__iec_) |
|
1511 __iec_(TIME) |
|
1512 #undef __iec_ |
|
1513 |
|
1514 /* Max for string data types */ |
|
1515 __extrem_(MAX_STRING, STRING, __STR_CMP(op1,tmp) < 0) /* The explicitly typed standard functions */ |
|
1516 __extrem_(MAX__STRING__STRING, STRING, __STR_CMP(op1,tmp) < 0) /* Overloaded function */ |
1174 |
1517 |
1175 /**************/ |
1518 /**************/ |
1176 /* MIN */ |
1519 /* MIN */ |
1177 /**************/ |
1520 /**************/ |
1178 #define __min_num(TYPENAME) __extrem_(__min_, TYPENAME, op1 > tmp) |
1521 /* Min for numerical data types */ |
1179 ANY_NBIT(__min_num) |
1522 #define __iec_(TYPENAME) \ |
1180 ANY_NUM(__min_num) |
1523 __extrem_(MIN_##TYPENAME, TYPENAME, op1 > tmp) /* The explicitly typed standard functions */\ |
1181 |
1524 __extrem_(MIN__##TYPENAME##__##TYPENAME, TYPENAME, op1 > tmp) /* Overloaded function */ |
1182 __extrem_(__min_, STRING, __STR_CMP(op1,tmp) > 0) |
1525 __ANY_NBIT(__iec_) |
1183 |
1526 __ANY_NUM(__iec_) |
1184 #define __min_time(TYPENAME) __extrem_(__min_, TYPENAME, __TIME_CMP(op1, tmp) > 0) |
1527 #undef __iec_ |
1185 |
1528 |
1186 /* Call previously defined macro for each concerned type */ |
1529 /* Min for time data types */ |
1187 ANY_DATE(__min_time) |
1530 #define __iec_(TYPENAME) \ |
1188 __min_time(TIME) |
1531 __extrem_(MIN_##TYPENAME, TYPENAME, __time_cmp(op1, tmp) > 0) /* The explicitly typed standard functions */\ |
|
1532 __extrem_(MIN__##TYPENAME##__##TYPENAME, TYPENAME, __time_cmp(op1, tmp) > 0) /* Overloaded function */ |
|
1533 __ANY_DATE(__iec_) |
|
1534 __iec_(TIME) |
|
1535 #undef __iec_ |
|
1536 |
|
1537 /* Min for string data types */ |
|
1538 __extrem_(MIN_STRING, STRING, __STR_CMP(op1,tmp) > 0) /* The explicitly typed standard functions */ |
|
1539 __extrem_(MIN__STRING__STRING, STRING, __STR_CMP(op1,tmp) > 0) /* Overloaded function */ |
|
1540 |
|
1541 /**************/ |
|
1542 /* LIMIT */ |
|
1543 /**************/ |
|
1544 |
|
1545 /* Limit for numerical data types */ |
|
1546 #define __iec_(TYPENAME)\ |
|
1547 /* The explicitly typed standard functions */\ |
|
1548 static inline TYPENAME LIMIT_##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1549 TEST_EN(TYPENAME)\ |
|
1550 return IN > MN ? IN < MX ? IN : MX : MN;\ |
|
1551 }\ |
|
1552 /* Overloaded function */\ |
|
1553 static inline TYPENAME LIMIT__##TYPENAME##__##TYPENAME##__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1554 TEST_EN(TYPENAME)\ |
|
1555 return IN > MN ? IN < MX ? IN : MX : MN;\ |
|
1556 } |
|
1557 __ANY_NBIT(__iec_) |
|
1558 __ANY_NUM(__iec_) |
|
1559 #undef __iec_ |
|
1560 |
|
1561 |
|
1562 /* Limit for time data types */ |
|
1563 #define __iec_(TYPENAME)\ |
|
1564 /* The explicitly typed standard functions */\ |
|
1565 static inline TYPENAME LIMIT_##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1566 TEST_EN(TYPENAME)\ |
|
1567 return __time_cmp(IN, MN) > 0 ? /* IN>MN ?*/\ |
|
1568 __time_cmp(IN, MX) < 0 ? /* IN<MX ?*/\ |
|
1569 IN : MX : MN;\ |
|
1570 }\ |
|
1571 /* Overloaded function */\ |
|
1572 static inline TYPENAME LIMIT__##TYPENAME##__##TYPENAME##__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, TYPENAME MN, TYPENAME IN, TYPENAME MX){\ |
|
1573 TEST_EN(TYPENAME)\ |
|
1574 return __time_cmp(IN, MN) > 0 ? /* IN>MN ?*/\ |
|
1575 __time_cmp(IN, MX) < 0 ? /* IN<MX ?*/\ |
|
1576 IN : MX : MN;\ |
|
1577 } |
|
1578 |
|
1579 __ANY_DATE(__iec_) |
|
1580 __iec_(TIME) |
|
1581 #undef __iec_ |
|
1582 |
|
1583 /* Limit for string data types */ |
|
1584 /* The explicitly typed standard functions */ |
|
1585 static inline STRING LIMIT_STRING(EN_ENO_PARAMS, STRING MN, STRING IN, STRING MX){ |
|
1586 TEST_EN(STRING) |
|
1587 return __STR_CMP(IN, MN) > 0 ? __STR_CMP(IN, MX) < 0 ? IN : MX : MN; |
|
1588 } |
|
1589 |
|
1590 /* Overloaded function */ |
|
1591 static inline STRING LIMIT__STRING__STRING__STRING__STRING(EN_ENO_PARAMS, STRING MN, STRING IN, STRING MX){ |
|
1592 TEST_EN(STRING) |
|
1593 return __STR_CMP(IN, MN) > 0 ? __STR_CMP(IN, MX) < 0 ? IN : MX : MN; |
|
1594 } |
|
1595 |
1189 |
1596 |
1190 /**************/ |
1597 /**************/ |
1191 /* MUX */ |
1598 /* MUX */ |
1192 /**************/ |
1599 /**************/ |
1193 #define __mux_(TYPENAME) \ |
1600 /* The standard states that the inputs for SEL and MUX must be named starting off from 0, |
1194 static inline TYPENAME __mux_##TYPENAME(EN_ENO_PARAMS, UINT param_count, UINT K, ...){\ |
1601 * unlike remaining functions, that start off at 1. |
|
1602 */ |
|
1603 /* The explicitly typed standard functions */ |
|
1604 #define __in1_anyint_(in2_TYPENAME) __ANY_INT_1(__iec_,in2_TYPENAME) |
|
1605 #define __iec_(in1_TYPENAME,in2_TYPENAME) \ |
|
1606 static inline in2_TYPENAME MUX__##in2_TYPENAME##__##in1_TYPENAME##__##in2_TYPENAME(EN_ENO_PARAMS, UINT param_count, in1_TYPENAME K, ...){\ |
1195 va_list ap;\ |
1607 va_list ap;\ |
1196 UINT i;\ |
1608 UINT i;\ |
1197 TYPENAME tmp;\ |
1609 in2_TYPENAME tmp;\ |
1198 TEST_EN_COND(TYPENAME, K >= param_count)\ |
1610 TEST_EN_COND(in2_TYPENAME, K >= param_count)\ |
1199 tmp = __INIT_##TYPENAME;\ |
1611 tmp = __INIT_##in2_TYPENAME;\ |
1200 \ |
1612 \ |
1201 va_start (ap, K); /* Initialize the argument list. */\ |
1613 va_start (ap, K); /* Initialize the argument list. */\ |
1202 \ |
1614 \ |
1203 for (i = 0; i < param_count; i++){\ |
1615 for (i = 0; i < param_count; i++){\ |
1204 if(K == i){\ |
1616 if(K == i){\ |
1205 tmp = va_arg (ap, VA_ARGS_##TYPENAME);\ |
1617 tmp = va_arg (ap, VA_ARGS_##in2_TYPENAME);\ |
1206 va_end (ap); /* Clean up. */\ |
1618 va_end (ap); /* Clean up. */\ |
1207 return tmp;\ |
1619 return tmp;\ |
1208 }else{\ |
1620 }else{\ |
1209 va_arg (ap, VA_ARGS_##TYPENAME);\ |
1621 va_arg (ap, VA_ARGS_##in2_TYPENAME);\ |
1210 }\ |
1622 }\ |
1211 }\ |
1623 }\ |
1212 \ |
1624 \ |
1213 va_end (ap); /* Clean up. */\ |
1625 va_end (ap); /* Clean up. */\ |
1214 return tmp;\ |
1626 return tmp;\ |
1215 } |
1627 } |
1216 |
1628 |
1217 ANY(__mux_) |
1629 __ANY(__in1_anyint_) |
1218 |
1630 #undef __iec_ |
1219 /**************/ |
1631 |
1220 /* Comparison */ |
1632 |
1221 /**************/ |
1633 /******************************************/ |
|
1634 /*** Table 28 ***/ |
|
1635 /*** Standard comparison functions ***/ |
|
1636 /******************************************/ |
1222 |
1637 |
1223 #define __compare_(fname,TYPENAME, COND) \ |
1638 #define __compare_(fname,TYPENAME, COND) \ |
1224 static inline BOOL fname##TYPENAME(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
1639 static inline BOOL fname(EN_ENO_PARAMS, UINT param_count, TYPENAME op1, ...){\ |
1225 va_list ap;\ |
1640 va_list ap;\ |
1226 UINT i;\ |
1641 UINT i;\ |
1227 TEST_EN(BOOL)\ |
1642 TEST_EN(BOOL)\ |
1228 \ |
1643 \ |
1229 va_start (ap, op1); /* Initialize the argument list. */\ |
1644 va_start (ap, op1); /* Initialize the argument list. */\ |
1244 va_end (ap); /* Clean up. */\ |
1659 va_end (ap); /* Clean up. */\ |
1245 return 1;\ |
1660 return 1;\ |
1246 } |
1661 } |
1247 |
1662 |
1248 #define __compare_num(fname, TYPENAME, TEST) __compare_(fname, TYPENAME, op1 TEST tmp ) |
1663 #define __compare_num(fname, TYPENAME, TEST) __compare_(fname, TYPENAME, op1 TEST tmp ) |
1249 #define __compare_time(fname, TYPENAME, TEST) __compare_(fname, TYPENAME, __TIME_CMP(op1, tmp) TEST 0) |
1664 #define __compare_time(fname, TYPENAME, TEST) __compare_(fname, TYPENAME, __time_cmp(op1, tmp) TEST 0) |
1250 #define __compare_string(fname, TEST) __compare_(fname, STRING, __STR_CMP(op1, tmp) TEST 0 ) |
1665 #define __compare_string(fname, TEST) __compare_(fname, STRING, __STR_CMP(op1, tmp) TEST 0 ) |
1251 |
1666 |
1252 |
1667 |
1253 /**************/ |
1668 /**************/ |
1254 /* GT */ |
1669 /* GT */ |
1255 /**************/ |
1670 /**************/ |
1256 |
1671 /* Comparison for numerical data types */ |
1257 #define __gt_num(TYPENAME) __compare_num(__gt_, TYPENAME, > ) |
1672 #define __iec_(TYPENAME) \ |
1258 ANY_NBIT(__gt_num) |
1673 __compare_num(GT_##TYPENAME, TYPENAME, > ) /* The explicitly typed standard functions */\ |
1259 ANY_NUM(__gt_num) |
1674 __compare_num(GT__BOOL__##TYPENAME, TYPENAME, > ) /* Overloaded function */ |
1260 |
1675 __ANY_NBIT(__iec_) |
1261 #define __gt_time(TYPENAME) __compare_time(__gt_, TYPENAME, > ) |
1676 __ANY_NUM(__iec_) |
1262 ANY_DATE(__gt_time) |
1677 #undef __iec_ |
1263 __gt_time(TIME) |
1678 |
1264 |
1679 /* Comparison for time data types */ |
1265 __compare_string(__gt_, > ) |
1680 #define __iec_(TYPENAME) \ |
|
1681 __compare_time(GT_##TYPENAME, TYPENAME, > ) /* The explicitly typed standard functions */\ |
|
1682 __compare_time(GT__BOOL__##TYPENAME, TYPENAME, > ) /* Overloaded function */ |
|
1683 __ANY_DATE(__iec_) |
|
1684 __iec_(TIME) |
|
1685 #undef __iec_ |
|
1686 |
|
1687 /* Comparison for string data types */ |
|
1688 __compare_string(GT_STRING, > ) /* The explicitly typed standard functions */ |
|
1689 __compare_string(GT__BOOL__STRING, > ) /* Overloaded function */ |
1266 |
1690 |
1267 /**************/ |
1691 /**************/ |
1268 /* GE */ |
1692 /* GE */ |
1269 /**************/ |
1693 /**************/ |
1270 |
1694 /* Comparison for numerical data types */ |
1271 #define __ge_num(TYPENAME) __compare_num(__ge_, TYPENAME, >= ) |
1695 #define __iec_(TYPENAME) \ |
1272 ANY_BIT(__ge_num) |
1696 __compare_num(GE_##TYPENAME, TYPENAME, >= ) /* The explicitly typed standard functions */\ |
1273 ANY_NUM(__ge_num) |
1697 __compare_num(GE__BOOL__##TYPENAME, TYPENAME, >= ) /* Overloaded function */ |
1274 |
1698 __ANY_NBIT(__iec_) |
1275 #define __ge_time(TYPENAME) __compare_time(__ge_, TYPENAME, >= ) |
1699 __ANY_NUM(__iec_) |
1276 ANY_DATE(__ge_time) |
1700 #undef __iec_ |
1277 __ge_time(TIME) |
1701 |
1278 |
1702 /* Comparison for time data types */ |
1279 __compare_string(__ge_, >=) |
1703 #define __iec_(TYPENAME) \ |
|
1704 __compare_time(GE_##TYPENAME, TYPENAME, >= ) /* The explicitly typed standard functions */\ |
|
1705 __compare_time(GE__BOOL__##TYPENAME, TYPENAME, >= ) /* Overloaded function */ |
|
1706 __ANY_DATE(__iec_) |
|
1707 __iec_(TIME) |
|
1708 #undef __iec_ |
|
1709 |
|
1710 /* Comparison for string data types */ |
|
1711 __compare_string(GE_STRING, >= ) /* The explicitly typed standard functions */ |
|
1712 __compare_string(GE__BOOL__STRING, >= ) /* Overloaded function */ |
|
1713 |
|
1714 |
1280 |
1715 |
1281 /**************/ |
1716 /**************/ |
1282 /* EQ */ |
1717 /* EQ */ |
1283 /**************/ |
1718 /**************/ |
1284 |
1719 /* Comparison for numerical data types */ |
1285 #define __eq_num(TYPENAME) __compare_num(__eq_, TYPENAME, == ) |
1720 #define __iec_(TYPENAME) \ |
1286 ANY_BIT(__eq_num) |
1721 __compare_num(EQ_##TYPENAME, TYPENAME, == ) /* The explicitly typed standard functions */\ |
1287 ANY_NUM(__eq_num) |
1722 __compare_num(EQ__BOOL__##TYPENAME, TYPENAME, == ) /* Overloaded function */ |
1288 |
1723 __ANY_NBIT(__iec_) |
1289 #define __eq_time(TYPENAME) __compare_time(__eq_, TYPENAME, == ) |
1724 __ANY_NUM(__iec_) |
1290 ANY_DATE(__eq_time) |
1725 #undef __iec_ |
1291 __eq_time(TIME) |
1726 |
1292 |
1727 /* Comparison for time data types */ |
1293 __compare_string(__eq_, == ) |
1728 #define __iec_(TYPENAME) \ |
|
1729 __compare_time(EQ_##TYPENAME, TYPENAME, == ) /* The explicitly typed standard functions */\ |
|
1730 __compare_time(EQ__BOOL__##TYPENAME, TYPENAME, == ) /* Overloaded function */ |
|
1731 __ANY_DATE(__iec_) |
|
1732 __iec_(TIME) |
|
1733 #undef __iec_ |
|
1734 |
|
1735 /* Comparison for string data types */ |
|
1736 __compare_string(EQ_STRING, == ) /* The explicitly typed standard functions */ |
|
1737 __compare_string(EQ__BOOL__STRING, == ) /* Overloaded function */ |
|
1738 |
1294 |
1739 |
1295 /**************/ |
1740 /**************/ |
1296 /* LT */ |
1741 /* LT */ |
1297 /**************/ |
1742 /**************/ |
1298 |
1743 /* Comparison for numerical data types */ |
1299 #define __lt_num(TYPENAME) __compare_num(__lt_, TYPENAME, < ) |
1744 #define __iec_(TYPENAME) \ |
1300 ANY_BIT(__lt_num) |
1745 __compare_num(LT_##TYPENAME, TYPENAME, < ) /* The explicitly typed standard functions */\ |
1301 ANY_NUM(__lt_num) |
1746 __compare_num(LT__BOOL__##TYPENAME, TYPENAME, < ) /* Overloaded function */ |
1302 |
1747 __ANY_NBIT(__iec_) |
1303 #define __lt_time(TYPENAME) __compare_time(__lt_, TYPENAME, < ) |
1748 __ANY_NUM(__iec_) |
1304 ANY_DATE(__lt_time) |
1749 #undef __iec_ |
1305 __lt_time(TIME) |
1750 |
1306 |
1751 /* Comparison for time data types */ |
1307 __compare_string(__lt_, < ) |
1752 #define __iec_(TYPENAME) \ |
|
1753 __compare_time(LT_##TYPENAME, TYPENAME, < ) /* The explicitly typed standard functions */\ |
|
1754 __compare_time(LT__BOOL__##TYPENAME, TYPENAME, < ) /* Overloaded function */ |
|
1755 __ANY_DATE(__iec_) |
|
1756 __iec_(TIME) |
|
1757 #undef __iec_ |
|
1758 |
|
1759 /* Comparison for string data types */ |
|
1760 __compare_string(LT_STRING, < ) /* The explicitly typed standard functions */ |
|
1761 __compare_string(LT__BOOL__STRING, < ) /* Overloaded function */ |
|
1762 |
1308 |
1763 |
1309 /**************/ |
1764 /**************/ |
1310 /* LE */ |
1765 /* LE */ |
1311 /**************/ |
1766 /**************/ |
1312 |
1767 /* Comparison for numerical data types */ |
1313 #define __le_num(TYPENAME) __compare_num(__le_, TYPENAME, <= ) |
1768 #define __iec_(TYPENAME) \ |
1314 ANY_BIT(__le_num) |
1769 __compare_num(LE_##TYPENAME, TYPENAME, <= ) /* The explicitly typed standard functions */\ |
1315 ANY_NUM(__le_num) |
1770 __compare_num(LE__BOOL__##TYPENAME, TYPENAME, <= ) /* Overloaded function */ |
1316 |
1771 __ANY_NBIT(__iec_) |
1317 #define __le_time(TYPENAME) __compare_time(__le_, TYPENAME, <= ) |
1772 __ANY_NUM(__iec_) |
1318 ANY_DATE(__le_time) |
1773 #undef __iec_ |
1319 __le_time(TIME) |
1774 |
1320 |
1775 /* Comparison for time data types */ |
1321 __compare_string(__le_, <= ) |
1776 #define __iec_(TYPENAME) \ |
|
1777 __compare_time(LE_##TYPENAME, TYPENAME, <= ) /* The explicitly typed standard functions */\ |
|
1778 __compare_time(LE__BOOL__##TYPENAME, TYPENAME, <= ) /* Overloaded function */ |
|
1779 __ANY_DATE(__iec_) |
|
1780 __iec_(TIME) |
|
1781 #undef __iec_ |
|
1782 |
|
1783 /* Comparison for string data types */ |
|
1784 __compare_string(LE_STRING, <= ) /* The explicitly typed standard functions */ |
|
1785 __compare_string(LE__BOOL__STRING, <= ) /* Overloaded function */ |
|
1786 |
1322 |
1787 |
1323 /**************/ |
1788 /**************/ |
1324 /* NE */ |
1789 /* NE */ |
1325 /**************/ |
1790 /**************/ |
1326 |
1791 /* Comparison for numerical data types */ |
1327 #define __ne_num(TYPENAME) __compare_num(__ne_, TYPENAME, != ) |
1792 #define __iec_(TYPENAME) \ |
1328 ANY_BIT(__ne_num) |
1793 __compare_num(NE_##TYPENAME, TYPENAME, != ) /* The explicitly typed standard functions */\ |
1329 ANY_NUM(__ne_num) |
1794 __compare_num(NE__BOOL__##TYPENAME##__##TYPENAME, TYPENAME, != ) /* Overloaded function */ |
1330 |
1795 __ANY_NBIT(__iec_) |
1331 #define __ne_time(TYPENAME) __compare_time(__ne_, TYPENAME, != ) |
1796 __ANY_NUM(__iec_) |
1332 ANY_DATE(__ne_time) |
1797 #undef __iec_ |
1333 __ne_time(TIME) |
1798 |
1334 |
1799 /* Comparison for time data types */ |
1335 __compare_string(__ne_, != ) |
1800 #define __iec_(TYPENAME) \ |
1336 |
1801 __compare_time(NE_##TYPENAME, TYPENAME, != ) /* The explicitly typed standard functions */\ |
|
1802 __compare_time(NE__BOOL__##TYPENAME##__##TYPENAME, TYPENAME, != ) /* Overloaded function */ |
|
1803 __ANY_DATE(__iec_) |
|
1804 __iec_(TIME) |
|
1805 #undef __iec_ |
|
1806 |
|
1807 /* Comparison for string data types */ |
|
1808 __compare_string(NE_STRING, != ) /* The explicitly typed standard functions */ |
|
1809 __compare_string(NE__BOOL__STRING__STRING, != ) /* Overloaded function */ |
|
1810 |
|
1811 |
|
1812 |
|
1813 |
|
1814 |
|
1815 |
|
1816 /*********************************************/ |
|
1817 /*********************************************/ |
|
1818 /* 2.5.1.5.5 Character string Functions */ |
|
1819 /*********************************************/ |
|
1820 /*********************************************/ |
|
1821 |
|
1822 /*************************************/ |
|
1823 /*** Table 29 ***/ |
|
1824 /*** Character string Functions ***/ |
|
1825 /*************************************/ |
|
1826 |
|
1827 /* We do not delcare explcitly typed versions of the functions in table 29. |
|
1828 * See note above regarding explicitly typed functions for more details. |
|
1829 */ |
|
1830 |
|
1831 |
|
1832 #define __STR_CMP(str1, str2) memcmp((char*)&str1.body,(char*)&str2.body, str1.len < str2.len ? str1.len : str2.len) |
|
1833 |
|
1834 |
|
1835 /***************/ |
|
1836 /* LEN */ |
|
1837 /***************/ |
|
1838 static inline __strlen_t __len(STRING IN) {return IN.len;} |
|
1839 |
|
1840 /* A function, with 1 input paramter, implementing a generic OPERATION */ |
|
1841 #define __genoper_1p_(fname,ret_TYPENAME, par_TYPENAME, OPERATION) \ |
|
1842 static inline ret_TYPENAME fname(EN_ENO_PARAMS, par_TYPENAME par1){\ |
|
1843 TEST_EN(ret_TYPENAME)\ |
|
1844 return (ret_TYPENAME)OPERATION(par1);\ |
|
1845 } |
|
1846 |
|
1847 #define __iec_(TYPENAME) __genoper_1p_(LEN__##TYPENAME##__STRING, TYPENAME, STRING, __len) |
|
1848 __ANY_INT(__iec_) |
|
1849 #undef __iec_ |
|
1850 |
|
1851 |
|
1852 /****************/ |
|
1853 /* LEFT */ |
|
1854 /****************/ |
|
1855 |
|
1856 static inline STRING __left(STRING IN, __strlen_t L){ |
|
1857 STRING res; |
|
1858 res = __INIT_STRING; |
|
1859 L = L < IN.len ? L : IN.len; |
|
1860 memcpy(&res.body, &IN.body, L); |
|
1861 res.len = L; |
|
1862 return res; |
|
1863 } |
|
1864 |
|
1865 #define __iec_(TYPENAME) \ |
|
1866 static inline STRING LEFT__STRING__STRING__##TYPENAME(EN_ENO_PARAMS, STRING str, TYPENAME L){\ |
|
1867 TEST_EN_COND(STRING, L < 0)\ |
|
1868 return (STRING)__left(str,L);\ |
|
1869 } |
|
1870 __ANY_INT(__iec_) |
|
1871 #undef __iec_ |
|
1872 |
|
1873 |
|
1874 /*****************/ |
|
1875 /* RIGHT */ |
|
1876 /*****************/ |
|
1877 |
|
1878 static inline STRING __right(STRING IN, __strlen_t L){ |
|
1879 STRING res; |
|
1880 res = __INIT_STRING; |
|
1881 L = L < IN.len ? L : IN.len; |
|
1882 memcpy(&res.body, &IN.body[IN.len - L], L); |
|
1883 res.len = L; |
|
1884 return res; |
|
1885 } |
|
1886 |
|
1887 |
|
1888 #define __iec_(TYPENAME) \ |
|
1889 static inline STRING RIGHT__STRING__STRING__##TYPENAME(EN_ENO_PARAMS, STRING str, TYPENAME L){\ |
|
1890 TEST_EN_COND(STRING, L < 0)\ |
|
1891 return (STRING)__right(str,L);\ |
|
1892 } |
|
1893 __ANY_INT(__iec_) |
|
1894 #undef __iec_ |
|
1895 |
|
1896 |
|
1897 /***************/ |
|
1898 /* MID */ |
|
1899 /***************/ |
|
1900 |
|
1901 static inline STRING __mid(STRING IN, __strlen_t L, __strlen_t P){ |
|
1902 STRING res; |
|
1903 res = __INIT_STRING; |
|
1904 if(P <= IN.len){ |
|
1905 P -= 1; /* now can be used as [index]*/ |
|
1906 L = L + P <= IN.len ? L : IN.len - P; |
|
1907 memcpy(&res.body, &IN.body[P] , L); |
|
1908 res.len = L; |
|
1909 } |
|
1910 return res; |
|
1911 } |
|
1912 |
|
1913 #define __iec_(TYPENAME) \ |
|
1914 static inline STRING MID__STRING__STRING__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, STRING str, TYPENAME L, TYPENAME P){\ |
|
1915 TEST_EN_COND(STRING, L < 0 || P < 0)\ |
|
1916 return (STRING)__mid(str,L,P);\ |
|
1917 } |
|
1918 __ANY_INT(__iec_) |
|
1919 #undef __iec_ |
|
1920 |
|
1921 |
|
1922 /******************/ |
|
1923 /* CONCAT */ |
|
1924 /******************/ |
|
1925 |
|
1926 static inline STRING CONCAT__STRING__STRING(UINT param_count, ...){ |
|
1927 UINT i; |
|
1928 STRING res; |
|
1929 va_list ap; |
|
1930 __strlen_t charcount; |
|
1931 charcount = 0; |
|
1932 res = __INIT_STRING; |
|
1933 |
|
1934 va_start (ap, param_count); /* Initialize the argument list. */ |
|
1935 |
|
1936 for (i = 0; i < param_count && charcount < STR_MAX_LEN; i++) |
|
1937 { |
|
1938 STRING tmp = va_arg(ap, STRING); |
|
1939 __strlen_t charrem = STR_MAX_LEN - charcount; |
|
1940 __strlen_t to_write = tmp.len > charrem ? charrem : tmp.len; |
|
1941 memcpy(&res.body[charcount], &tmp.body , to_write); |
|
1942 charcount += to_write; |
|
1943 } |
|
1944 |
|
1945 res.len = charcount; |
|
1946 |
|
1947 va_end (ap); /* Clean up. */ |
|
1948 return res; |
|
1949 } |
|
1950 |
|
1951 /******************/ |
|
1952 /* INSERT */ |
|
1953 /******************/ |
|
1954 |
|
1955 static inline STRING __insert(STRING IN1, STRING IN2, __strlen_t P){ |
|
1956 STRING res; |
|
1957 __strlen_t to_copy; |
|
1958 res = __INIT_STRING; |
|
1959 |
|
1960 to_copy = P > IN1.len ? IN1.len : P; |
|
1961 memcpy(&res.body, &IN1.body , to_copy); |
|
1962 P = res.len = to_copy; |
|
1963 |
|
1964 to_copy = IN2.len + res.len > STR_MAX_LEN ? STR_MAX_LEN - res.len : IN2.len; |
|
1965 memcpy(&res.body[res.len], &IN2.body , to_copy); |
|
1966 res.len += to_copy; |
|
1967 |
|
1968 to_copy = IN1.len - P < STR_MAX_LEN - res.len ? IN1.len - P : STR_MAX_LEN - res.len ; |
|
1969 memcpy(&res.body[res.len], &IN1.body[P] , to_copy); |
|
1970 res.len += to_copy; |
|
1971 |
|
1972 return res; |
|
1973 } |
|
1974 |
|
1975 #define __iec_(TYPENAME) \ |
|
1976 static inline STRING INSERT__STRING__STRING__STRING__##TYPENAME(EN_ENO_PARAMS, STRING str1, STRING str2, TYPENAME P){\ |
|
1977 TEST_EN_COND(STRING, P < 0)\ |
|
1978 return (STRING)__insert(str1,str2,P);\ |
|
1979 } |
|
1980 __ANY_INT(__iec_) |
|
1981 #undef __iec_ |
|
1982 |
|
1983 |
|
1984 /******************/ |
|
1985 /* DELETE */ |
|
1986 /******************/ |
|
1987 |
|
1988 static inline STRING __delete(STRING IN, __strlen_t L, __strlen_t P){ |
|
1989 STRING res; |
|
1990 __strlen_t to_copy; |
|
1991 res = __INIT_STRING; |
|
1992 |
|
1993 to_copy = P > IN.len ? IN.len : P-1; |
|
1994 memcpy(&res.body, &IN.body , to_copy); |
|
1995 P = res.len = to_copy; |
|
1996 |
|
1997 if( IN.len > P + L ){ |
|
1998 to_copy = IN.len - P - L; |
|
1999 memcpy(&res.body[res.len], &IN.body[P + L], to_copy); |
|
2000 res.len += to_copy; |
|
2001 } |
|
2002 |
|
2003 return res; |
|
2004 } |
|
2005 |
|
2006 #define __iec_(TYPENAME) \ |
|
2007 static inline STRING DELETE__STRING__STRING__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, STRING str, TYPENAME L, TYPENAME P){\ |
|
2008 TEST_EN_COND(STRING, L < 0 || P < 0)\ |
|
2009 return (STRING)__delete(str,L,P);\ |
|
2010 } |
|
2011 __ANY_INT(__iec_) |
|
2012 #undef __iec_ |
|
2013 |
|
2014 |
|
2015 /*******************/ |
|
2016 /* REPLACE */ |
|
2017 /*******************/ |
|
2018 |
|
2019 static inline STRING __replace(STRING IN1, STRING IN2, __strlen_t L, __strlen_t P){ |
|
2020 STRING res; |
|
2021 __strlen_t to_copy; |
|
2022 res = __INIT_STRING; |
|
2023 |
|
2024 to_copy = P > IN1.len ? IN1.len : P-1; |
|
2025 memcpy(&res.body, &IN1.body , to_copy); |
|
2026 P = res.len = to_copy; |
|
2027 |
|
2028 to_copy = IN2.len < L ? IN2.len : L; |
|
2029 |
|
2030 if( to_copy + res.len > STR_MAX_LEN ) |
|
2031 to_copy = STR_MAX_LEN - res.len; |
|
2032 |
|
2033 memcpy(&res.body[res.len], &IN2.body , to_copy); |
|
2034 res.len += to_copy; |
|
2035 |
|
2036 P += L; |
|
2037 if( res.len < STR_MAX_LEN && P < IN1.len) |
|
2038 { |
|
2039 to_copy = IN1.len - P; |
|
2040 memcpy(&res.body[res.len], &IN1.body[P] , to_copy); |
|
2041 res.len += to_copy; |
|
2042 } |
|
2043 |
|
2044 return res; |
|
2045 } |
|
2046 |
|
2047 #define __iec_(TYPENAME) \ |
|
2048 static inline STRING REPLACE__STRING__STRING__STRING__##TYPENAME##__##TYPENAME(EN_ENO_PARAMS, STRING str1, STRING str2, TYPENAME L, TYPENAME P){\ |
|
2049 TEST_EN_COND(STRING, L < 0 || P < 0)\ |
|
2050 return (STRING)__replace(str1,str2,L,P);\ |
|
2051 } |
|
2052 __ANY_INT(__iec_) |
|
2053 #undef __iec_ |
|
2054 |
|
2055 /****************/ |
|
2056 /* FIND */ |
|
2057 /****************/ |
|
2058 |
|
2059 static inline __strlen_t __pfind(STRING* IN1, STRING* IN2){ |
|
2060 UINT count1 = 0; /* offset of first matching char in IN1 */ |
|
2061 UINT count2 = 0; /* count of matching char */ |
|
2062 while(count1 + count2 < IN1->len && count2 < IN2->len) |
|
2063 { |
|
2064 if(IN1->body[count1 + count2] != IN2->body[count2]){ |
|
2065 count1 += count2 + 1; |
|
2066 count2 = 0; |
|
2067 } |
|
2068 else { |
|
2069 count2++; |
|
2070 } |
|
2071 } |
|
2072 return count2 == IN2->len -1 ? 0 : count1 + 1; |
|
2073 } |
|
2074 |
|
2075 #define __iec_(TYPENAME) \ |
|
2076 static inline TYPENAME FIND__##TYPENAME##__STRING__STRING(EN_ENO_PARAMS, STRING str1, STRING str2){\ |
|
2077 TEST_EN(TYPENAME)\ |
|
2078 return (TYPENAME)__pfind(&str1,&str2);\ |
|
2079 } |
|
2080 __ANY_INT(__iec_) |
|
2081 #undef __iec_ |
|
2082 |
|
2083 |
|
2084 /*********************************************/ |
|
2085 /*********************************************/ |
|
2086 /* 2.5.1.5.6 Functions of time data types */ |
|
2087 /*********************************************/ |
|
2088 /*********************************************/ |
|
2089 |
|
2090 /**************************************/ |
|
2091 /*** Table 30 ***/ |
|
2092 /*** Functions of time data types ***/ |
|
2093 /**************************************/ |
|
2094 |
|
2095 |
|
2096 static inline TIME ADD_TIME(EN_ENO_PARAMS, TIME IN1, TIME IN2){ |
|
2097 TEST_EN(TIME) |
|
2098 return __time_add(IN1, IN2); |
|
2099 } |
|
2100 |
|
2101 static inline TOD ADD_TOD_TIME(EN_ENO_PARAMS, TOD IN1, TIME IN2){ |
|
2102 TEST_EN(TOD) |
|
2103 return __time_add(IN1, IN2); |
|
2104 } |
|
2105 |
|
2106 static inline DT ADD_DT_TIME(EN_ENO_PARAMS, DT IN1, TIME IN2){ |
|
2107 TEST_EN(DT) |
|
2108 return __time_add(IN1, IN2); |
|
2109 } |
|
2110 |
|
2111 static inline TIME SUB_TIME(EN_ENO_PARAMS, TIME IN1, TIME IN2){ |
|
2112 TEST_EN(TIME) |
|
2113 return __time_sub(IN1, IN2); |
|
2114 } |
|
2115 |
|
2116 static inline TIME SUB_DATE_DATE(EN_ENO_PARAMS, DATE IN1, DATE IN2){ |
|
2117 TEST_EN(TIME) |
|
2118 return __time_sub(IN1, IN2); |
|
2119 } |
|
2120 |
|
2121 static inline TOD SUB_TOD_TIME(EN_ENO_PARAMS, TOD IN1, TIME IN2){ |
|
2122 TEST_EN(TOD) |
|
2123 return __time_sub(IN1, IN2); |
|
2124 } |
|
2125 |
|
2126 static inline TIME SUB_TOD_TOD(EN_ENO_PARAMS, TOD IN1, TOD IN2){ |
|
2127 TEST_EN(TIME) |
|
2128 return __time_sub(IN1, IN2); |
|
2129 } |
|
2130 |
|
2131 static inline DT SUB_DT_TIME(EN_ENO_PARAMS, DT IN1, TIME IN2){ |
|
2132 TEST_EN(DT) |
|
2133 return __time_sub(IN1, IN2); |
|
2134 } |
|
2135 |
|
2136 static inline TIME SUB_DT_DT(EN_ENO_PARAMS, DT IN1, DT IN2){ |
|
2137 TEST_EN(TIME) |
|
2138 return __time_sub(IN1, IN2); |
|
2139 } |
|
2140 |
|
2141 |
|
2142 /*** MULTIME ***/ |
|
2143 #define __iec_(TYPENAME)\ |
|
2144 static inline TIME MULTIME__TIME__TIME__##TYPENAME(EN_ENO_PARAMS, TIME IN1, TYPENAME IN2){\ |
|
2145 TEST_EN(TIME)\ |
|
2146 return __time_mul(IN1, IN2);\ |
|
2147 } |
|
2148 __ANY_NUM(__iec_) |
|
2149 #undef __iec_ |
|
2150 |
|
2151 /*** MUL ***/ |
|
2152 #define __iec_(TYPENAME)\ |
|
2153 static inline TIME MUL__TIME__TIME__##TYPENAME(EN_ENO_PARAMS, TIME IN1, TYPENAME IN2){\ |
|
2154 TEST_EN(TIME)\ |
|
2155 return __time_mul(IN1, IN2);\ |
|
2156 } |
|
2157 __ANY_NUM(__iec_) |
|
2158 #undef __iec_ |
|
2159 |
|
2160 /*** DIVTIME ***/ |
|
2161 #define __iec_(TYPENAME)\ |
|
2162 static inline TIME DIVTIME__TIME__TIME__##TYPENAME(EN_ENO_PARAMS, TIME IN1, TYPENAME IN2){\ |
|
2163 TEST_EN(TIME)\ |
|
2164 return __time_div(IN1, IN2);\ |
|
2165 } |
|
2166 __ANY_NUM(__iec_) |
|
2167 #undef __iec_ |
|
2168 |
|
2169 /*** DIV ***/ |
|
2170 #define __iec_(TYPENAME)\ |
|
2171 static inline TIME DIV__TIME__TIME__##TYPENAME(EN_ENO_PARAMS, TIME IN1, TYPENAME IN2){\ |
|
2172 TEST_EN(TIME)\ |
|
2173 return __time_div(IN1, IN2);\ |
|
2174 } |
|
2175 __ANY_NUM(__iec_) |
|
2176 #undef __iec_ |
|
2177 |
|
2178 /*** CONCAT_DATE_TOD ***/ |
|
2179 static inline DT CONCAT_DATE_TOD(EN_ENO_PARAMS, DATE IN1, TOD IN2){ |
|
2180 TEST_EN(DT) |
|
2181 return __time_add(IN1, IN2); |
|
2182 } |
|
2183 |
|
2184 |
|
2185 |
|
2186 /****************************************************/ |
|
2187 /****************************************************/ |
|
2188 /* 2.5.1.5.6 Functions of enumerated data types */ |
|
2189 /****************************************************/ |
|
2190 /****************************************************/ |
|
2191 |
|
2192 /********************************************/ |
|
2193 /*** Table 31 ***/ |
|
2194 /*** Functions of enumerated data types ***/ |
|
2195 /********************************************/ |
|
2196 |
|
2197 /* Do we support this? */ |