LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - batcalc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 648 880 73.6 %
Date: 2021-10-27 03:06:47 Functions: 48 76 63.2 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "gdk.h"
      11             : #include "mal_exception.h"
      12             : #include "mal_interpreter.h"
      13             : 
      14             : static str
      15          11 : mythrow(enum malexception type, const char *fcn, const char *msg)
      16             : {
      17          11 :         char *errbuf = GDKerrbuf;
      18             :         char *s;
      19             : 
      20          11 :         if (errbuf && *errbuf) {
      21          11 :                 if (strncmp(errbuf, "!ERROR: ", 8) == 0)
      22          11 :                         errbuf += 8;
      23          11 :                 if (strchr(errbuf, '!') == errbuf + 5) {
      24           0 :                         s = createException(type, fcn, "%s", errbuf);
      25          11 :                 } else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
      26          11 :                         s = createException(type, fcn, "%s", s + 2);
      27             :                 } else {
      28           0 :                         s = createException(type, fcn, "%s", errbuf);
      29             :                 }
      30          11 :                 GDKclrerr();
      31          11 :                 return s;
      32             :         }
      33           0 :         return createException(type, fcn, "%s", msg);
      34             : }
      35             : 
      36             : static str
      37       10739 : CMDbatUNARY(MalStkPtr stk, InstrPtr pci,
      38             :                         BAT *(*batfunc)(BAT *, BAT *), const char *malfunc)
      39             : {
      40             :         bat bid;
      41             :         BAT *bn, *b, *s = NULL;
      42             : 
      43       10739 :         bid = *getArgReference_bat(stk, pci, 1);
      44       10739 :         if ((b = BATdescriptor(bid)) == NULL)
      45           0 :                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      46       10739 :         if (pci->argc == 3) {
      47         131 :                 bid = *getArgReference_bat(stk, pci, 2);
      48         131 :                 if (!is_bat_nil(bid)) {
      49         114 :                         if ((s = BATdescriptor(bid)) == NULL) {
      50           0 :                                 BBPunfix(b->batCacheid);
      51           0 :                                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      52             :                         }
      53             :                 }
      54             :         }
      55             : 
      56       10739 :         bn = (*batfunc)(b, s);
      57       10740 :         BBPunfix(b->batCacheid);
      58       10740 :         if (s)
      59         114 :                 BBPunfix(s->batCacheid);
      60       10740 :         if (bn == NULL) {
      61           0 :                 return mythrow(MAL, malfunc, OPERATION_FAILED);
      62             :         }
      63       10740 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
      64       10740 :         BBPkeepref(bn->batCacheid);
      65       10739 :         return MAL_SUCCEED;
      66             : }
      67             : 
      68             : static str
      69           0 : CMDbatUNARY1(MalStkPtr stk, InstrPtr pci, bool abort_on_error,
      70             :                          BAT *(*batfunc)(BAT *, BAT *, bool), const char *malfunc)
      71             : {
      72             :         bat bid;
      73             :         BAT *bn, *b, *s = NULL;
      74             : 
      75           0 :         bid = *getArgReference_bat(stk, pci, 1);
      76           0 :         if ((b = BATdescriptor(bid)) == NULL)
      77           0 :                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      78           0 :         if (pci->argc == 3) {
      79           0 :                 bid = *getArgReference_bat(stk, pci, 2);
      80           0 :                 if (!is_bat_nil(bid)) {
      81           0 :                         if ((s = BATdescriptor(bid)) == NULL) {
      82           0 :                                 BBPunfix(b->batCacheid);
      83           0 :                                 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      84             :                         }
      85             :                 }
      86             :         }
      87             : 
      88           0 :         bn = (*batfunc)(b, s, abort_on_error);
      89           0 :         BBPunfix(b->batCacheid);
      90           0 :         if (s)
      91           0 :                 BBPunfix(s->batCacheid);
      92           0 :         if (bn == NULL) {
      93           0 :                 return mythrow(MAL, malfunc, OPERATION_FAILED);
      94             :         }
      95           0 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
      96           0 :         BBPkeepref(bn->batCacheid);
      97           0 :         return MAL_SUCCEED;
      98             : }
      99             : 
     100             : static str
     101           0 : CMDbatISZERO(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     102             : {
     103             :         (void) cntxt;
     104             :         (void) mb;
     105             : 
     106           0 :         return CMDbatUNARY(stk, pci, BATcalciszero, "batcalc.iszero");
     107             : }
     108             : 
     109             : static str
     110        2883 : CMDbatISNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     111             : {
     112             :         (void) cntxt;
     113             :         (void) mb;
     114             : 
     115        2883 :         return CMDbatUNARY(stk, pci, BATcalcisnil, "batcalc.isnil");
     116             : }
     117             : 
     118             : static str
     119        2425 : CMDbatISNOTNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     120             : {
     121             :         (void) cntxt;
     122             :         (void) mb;
     123             : 
     124        2425 :         return CMDbatUNARY(stk, pci, BATcalcisnotnil, "batcalc.isnotnil");
     125             : }
     126             : 
     127             : static str
     128         715 : CMDbatNOT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     129             : {
     130             :         (void) cntxt;
     131             :         (void) mb;
     132             : 
     133         715 :         return CMDbatUNARY(stk, pci, BATcalcnot, "batcalc.not");
     134             : }
     135             : 
     136             : static str
     137        4511 : CMDbatABS(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     138             : {
     139             :         (void) cntxt;
     140             :         (void) mb;
     141             : 
     142        4511 :         return CMDbatUNARY(stk, pci, BATcalcabsolute, "batcalc.abs");
     143             : }
     144             : 
     145             : static str
     146           0 : CMDbatINCR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     147             : {
     148             :         (void) cntxt;
     149             :         (void) mb;
     150             : 
     151           0 :         return CMDbatUNARY1(stk, pci, true, BATcalcincr, "batcalc.incr");
     152             : }
     153             : 
     154             : static str
     155           0 : CMDbatDECR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     156             : {
     157             :         (void) cntxt;
     158             :         (void) mb;
     159             : 
     160           0 :         return CMDbatUNARY1(stk, pci, true, BATcalcdecr, "batcalc.decr");
     161             : }
     162             : 
     163             : static str
     164         197 : CMDbatNEG(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     165             : {
     166             :         (void) cntxt;
     167             :         (void) mb;
     168             : 
     169         197 :         return CMDbatUNARY(stk, pci, BATcalcnegate, "batcalc.neg");
     170             : }
     171             : 
     172             : static str
     173           9 : CMDbatSIGN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     174             : {
     175             :         (void) cntxt;
     176             :         (void) mb;
     177             : 
     178           9 :         return CMDbatUNARY(stk, pci, BATcalcsign, "batcalc.sign");
     179             : }
     180             : 
     181             : static int
     182           0 : calctype(int tp1, int tp2)
     183             : {
     184           0 :         int tp1s = ATOMbasetype(tp1);
     185           0 :         int tp2s = ATOMbasetype(tp2);
     186           0 :         if (tp1s == TYPE_str && tp2s == TYPE_str)
     187             :                 return TYPE_str;
     188           0 :         if (tp1s < TYPE_flt && tp2s < TYPE_flt) {
     189           0 :                 if (tp1s > tp2s)
     190             :                         return tp1;
     191           0 :                 if (tp1s < tp2s)
     192             :                         return tp2;
     193           0 :                 return MAX(tp1, tp2);
     194             :         }
     195           0 :         if (tp1s == TYPE_dbl || tp2s == TYPE_dbl)
     196             :                 return TYPE_dbl;
     197           0 :         if (tp1s == TYPE_flt || tp2s == TYPE_flt)
     198             :                 return TYPE_flt;
     199             : #ifdef HAVE_HGE
     200           0 :         if (tp1s == TYPE_hge || tp2s == TYPE_hge)
     201           0 :                 return TYPE_hge;
     202             : #endif
     203             :         return TYPE_lng;
     204             : }
     205             : 
     206             : static int
     207           0 : calctypeenlarge(int tp1, int tp2)
     208             : {
     209           0 :         tp1 = calctype(tp1, tp2);
     210           0 :         switch (tp1) {
     211             :         case TYPE_bte:
     212             :                 return TYPE_sht;
     213           0 :         case TYPE_sht:
     214           0 :                 return TYPE_int;
     215           0 :         case TYPE_int:
     216           0 :                 return TYPE_lng;
     217             : #ifdef HAVE_HGE
     218           0 :         case TYPE_lng:
     219           0 :                 return TYPE_hge;
     220             : #endif
     221           0 :         case TYPE_flt:
     222           0 :                 return TYPE_dbl;
     223           0 :         default:
     224             :                 /* we shouldn't get here */
     225           0 :                 return tp1;
     226             :         }
     227             : }
     228             : 
     229             : static int
     230           0 : calcdivtype(int tp1, int tp2)
     231             : {
     232             :         /* if right hand side is floating point, the result is floating
     233             :          * point, otherwise the result has the type of the left hand
     234             :          * side */
     235           0 :         tp1 = ATOMbasetype(tp1);
     236           0 :         tp2 = ATOMbasetype(tp2);
     237           0 :         if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
     238             :                 return TYPE_dbl;
     239           0 :         if (tp1 == TYPE_flt || tp2 == TYPE_flt)
     240           0 :                 return TYPE_flt;
     241             :         return tp1;
     242             : }
     243             : 
     244             : #if 0
     245             : static int
     246             : calcdivtypeflt(int tp1, int tp2)
     247             : {
     248             :         (void) tp1;
     249             :         (void) tp2;
     250             :         return TYPE_flt;
     251             : }
     252             : 
     253             : static int
     254             : calcdivtypedbl(int tp1, int tp2)
     255             : {
     256             :         (void) tp1;
     257             :         (void) tp2;
     258             :         return TYPE_dbl;
     259             : }
     260             : #endif
     261             : 
     262             : static int
     263           0 : calcmodtype(int tp1, int tp2)
     264             : {
     265           0 :         tp1 = ATOMbasetype(tp1);
     266           0 :         tp2 = ATOMbasetype(tp2);
     267           0 :         assert(tp1 > 0 && tp1 < TYPE_str && tp1 != TYPE_bat && tp1 != TYPE_ptr);
     268           0 :         assert(tp2 > 0 && tp2 < TYPE_str && tp2 != TYPE_bat && tp2 != TYPE_ptr);
     269           0 :         if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
     270             :                 return TYPE_dbl;
     271           0 :         if (tp1 == TYPE_flt || tp2 == TYPE_flt)
     272             :                 return TYPE_flt;
     273           0 :         return MIN(tp1, tp2);
     274             : }
     275             : 
     276             : /* MAL function has one of the following signatures:
     277             :  * # without candidate list
     278             :  * func(b1:bat, b2:bat) :bat
     279             :  * func(b1:bat, v2:any) :bat
     280             :  * func(v1:any, b2:bat) :bat
     281             :  * # with candidate list
     282             :  * func(b1:bat, b2:bat, s1:bat, s2:bat) :bat
     283             :  * func(b1:bat, v2:any, s1:bat) :bat
     284             :  * func(v1:any, b2:bat, s2:bat) :bat
     285             :  */
     286             : static str
     287      130654 : CMDbatBINARY2(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
     288             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *, int, bool),
     289             :                           BAT *(batfunc1)(BAT *, const ValRecord *, BAT *, int, bool),
     290             :                           BAT *(batfunc2)(const ValRecord *, BAT *, BAT *, int, bool),
     291             :                           int (*typefunc)(int, int),
     292             :                           bool abort_on_error, const char *malfunc)
     293             : {
     294             :         bat bid;
     295             :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     296             :         int tp1, tp2, tp3;
     297             : 
     298      130654 :         tp1 = stk->stk[getArg(pci, 1)].vtype; /* first argument */
     299      130654 :         tp2 = stk->stk[getArg(pci, 2)].vtype; /* second argument */
     300      130654 :         tp3 = getArgType(mb, pci, 0);             /* return argument */
     301      130654 :         assert(isaBatType(tp3));
     302      130654 :         tp3 = getBatType(tp3);
     303             : 
     304      130654 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     305      129884 :                 bid = *getArgReference_bat(stk, pci, 1);
     306      129884 :                 b1 = BATdescriptor(bid);
     307      129880 :                 if (b1 == NULL)
     308           0 :                         goto bailout;
     309             :         }
     310             : 
     311      130650 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     312       51747 :                 bid = *getArgReference_bat(stk, pci, 2);
     313       51747 :                 b2 = BATdescriptor(bid);
     314       51750 :                 if (b2 == NULL)
     315           0 :                         goto bailout;
     316             :         }
     317             : 
     318      130653 :         if (pci->argc > 4) {
     319       50976 :                 assert(pci->argc == 5);
     320       50976 :                 bid = *getArgReference_bat(stk, pci, 4);
     321       50976 :                 if (!is_bat_nil(bid)) {
     322         131 :                         s2 = BATdescriptor(bid);
     323         131 :                         if (s2 == NULL)
     324           0 :                                 goto bailout;
     325             :                 }
     326             :         }
     327      130653 :         if (pci->argc > 3) {
     328      130634 :                 bid = *getArgReference_bat(stk, pci, 3);
     329      130634 :                 if (!is_bat_nil(bid)) {
     330        2414 :                         s1 = BATdescriptor(bid);
     331        2414 :                         if (s1 == NULL)
     332           0 :                                 goto bailout;
     333        2414 :                         if (b1 == NULL) {
     334             :                                 s2 = s1;
     335             :                                 s1 = NULL;
     336             :                         }
     337             :                 }
     338             :         }
     339             : 
     340      130653 :         if (b1 && b2) {
     341       50977 :                 if (tp3 == TYPE_any)
     342           0 :                         tp3 = (*typefunc)(b1->ttype, b2->ttype);
     343       50977 :                 bn = (*batfunc)(b1, b2, s1, s2, tp3, abort_on_error);
     344       79676 :         } else if (b1) {
     345       78906 :                 if (tp3 == TYPE_any)
     346           0 :                         tp3 = (*typefunc)(b1->ttype, tp2);
     347       78906 :                 bn = (*batfunc1)(b1, &stk->stk[getArg(pci, 2)], s1, tp3, abort_on_error);
     348         770 :         } else if (b2) {
     349         770 :                 if (tp3 == TYPE_any)
     350           0 :                         tp3 = (*typefunc)(tp1, b2->ttype);
     351         770 :                 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b2, s2, tp3, abort_on_error);
     352             :         } else
     353           0 :                 goto bailout;                   /* cannot happen */
     354      130644 :         if (b1)
     355      129875 :                 BBPunfix(b1->batCacheid);
     356      130662 :         if (b2)
     357       51749 :                 BBPunfix(b2->batCacheid);
     358      130654 :         if (s1)
     359        2407 :                 BBPunfix(s1->batCacheid);
     360      130654 :         if (s2)
     361         138 :                 BBPunfix(s2->batCacheid);
     362      130654 :         if (bn == NULL)
     363           4 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     364      130650 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     365      130650 :         BBPkeepref(bn->batCacheid);
     366      130637 :         return MAL_SUCCEED;
     367             : 
     368           0 : bailout:
     369           0 :         if (b1)
     370           0 :                 BBPunfix(b1->batCacheid);
     371           0 :         if (b2)
     372           0 :                 BBPunfix(b2->batCacheid);
     373             : /* cannot happen
     374             :         if (s1)
     375             :                 BBPunfix(s1->batCacheid);
     376             : */
     377           0 :         if (s2)
     378           0 :                 BBPunfix(s2->batCacheid);
     379           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     380             : }
     381             : 
     382             : /* MAL function has one of the signatures for CMDbatBINARY2, or one of
     383             :  * the following:
     384             :  * # without candidate list
     385             :  * func(b1:bat, b2:bat, abort_on_error:bit) :bat
     386             :  * func(b1:bat, v2:any, abort_on_error:bit) :bat
     387             :  * func(v1:any, b2:bat, abort_on_error:bit) :bat
     388             :  * # with candidate list
     389             :  * func(b1:bat, b2:bat, s1:bat, s2:bat, abort_on_error:bit) :bat
     390             :  * func(b1:bat, v2:any, s1:bat, abort_on_error:bit) :bat
     391             :  * func(v1:any, b2:bat, s2:bat, abort_on_error:bit) :bat
     392             :  */
     393             : static str
     394       46551 : CMDbatBINARY1(MalStkPtr stk, InstrPtr pci,
     395             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *, bool),
     396             :                           BAT *(*batfunc1)(BAT *, const ValRecord *, BAT *, bool),
     397             :                           BAT *(*batfunc2)(const ValRecord *, BAT *, BAT *, bool),
     398             :                           bool abort_on_error,
     399             :                           const char *malfunc)
     400             : {
     401             :         bat bid;
     402             :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     403             :         int tp1, tp2;
     404             : 
     405       46551 :         tp1 = stk->stk[getArg(pci, 1)].vtype; /* first argument */
     406       46551 :         tp2 = stk->stk[getArg(pci, 2)].vtype; /* second argument */
     407             : 
     408       46551 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     409       46471 :                 bid = *getArgReference_bat(stk, pci, 1);
     410       46471 :                 b1 = BATdescriptor(bid);
     411       46468 :                 if (b1 == NULL)
     412           0 :                         goto bailout;
     413             :         }
     414             : 
     415       46548 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     416       35928 :                 bid = *getArgReference_bat(stk, pci, 2);
     417       35928 :                 b2 = BATdescriptor(bid);
     418       35931 :                 if (b2 == NULL)
     419           0 :                         goto bailout;
     420             :         }
     421             : 
     422       46551 :         if (pci->argc > 5) {
     423           0 :                 assert(pci->argc == 6);
     424           0 :                 abort_on_error = *getArgReference_bit(stk, pci, 5);
     425             :         }
     426       46551 :         if (pci->argc > 4) {
     427         318 :                 if (stk->stk[getArg(pci, 4)].vtype == TYPE_bat) {
     428         318 :                         bid = *getArgReference_bat(stk, pci, 4);
     429         318 :                         if (!is_bat_nil(bid)) {
     430          93 :                                 s2 = BATdescriptor(bid);
     431          93 :                                 if (s2 == NULL)
     432           0 :                                         goto bailout;
     433             :                         }
     434             :                 } else {
     435           0 :                         assert(pci->argc == 5);
     436           0 :                         abort_on_error = *getArgReference_bit(stk, pci, 4);
     437             :                 }
     438             :         }
     439       46551 :         if (pci->argc > 3) {
     440       16973 :                 if (stk->stk[getArg(pci, 3)].vtype == TYPE_bat) {
     441        8973 :                         bid = *getArgReference_bat(stk, pci, 3);
     442        8973 :                         if (!is_bat_nil(bid)) {
     443        8730 :                                 s1 = BATdescriptor(bid);
     444        8727 :                                 if (s1 == NULL)
     445           0 :                                         goto bailout;
     446        8727 :                                 if (b1 == NULL) {
     447             :                                         s2 = s1;
     448             :                                         s1 = NULL;
     449             :                                 }
     450             :                         }
     451             :                 } else {
     452        8000 :                         assert(pci->argc == 4);
     453        8000 :                         abort_on_error = *getArgReference_bit(stk, pci, 3);
     454             :                 }
     455             :         }
     456             : 
     457       46548 :         if (b1 && b2)
     458       35850 :                 bn = (*batfunc)(b1, b2, s1, s2, abort_on_error);
     459       10698 :         else if (b1)
     460       10618 :                 bn = (*batfunc1)(b1, &stk->stk[getArg(pci, 2)], s1, abort_on_error);
     461          80 :         else if (b2)
     462          80 :                 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b2, s2, abort_on_error);
     463             :         else
     464           0 :                 goto bailout;                   /* cannot happen */
     465       46551 :         if (b1)
     466       46471 :                 BBPunfix(b1->batCacheid);
     467       46550 :         if (b2)
     468       35931 :                 BBPunfix(b2->batCacheid);
     469       46548 :         if (s1)
     470        8680 :                 BBPunfix(s1->batCacheid);
     471       46549 :         if (s2)
     472         141 :                 BBPunfix(s2->batCacheid);
     473       46549 :         if (bn == NULL)
     474           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     475       46549 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     476       46549 :         BBPkeepref(bn->batCacheid);
     477       46548 :         return MAL_SUCCEED;
     478             : 
     479           0 : bailout:
     480           0 :         if (b1)
     481           0 :                 BBPunfix(b1->batCacheid);
     482           0 :         if (b2)
     483           0 :                 BBPunfix(b2->batCacheid);
     484             : /* cannot happen
     485             :         if (s1)
     486             :                 BBPunfix(s1->batCacheid);
     487             : */
     488           0 :         if (s2)
     489           0 :                 BBPunfix(s2->batCacheid);
     490           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     491             : }
     492             : 
     493             : /* MAL function has one of the signatures for CMDbatBINARY2
     494             :  */
     495             : static str
     496       40067 : CMDbatBINARY0(MalStkPtr stk, InstrPtr pci,
     497             :                           BAT *(*batfunc)(BAT *, BAT *, BAT *, BAT *),
     498             :                           BAT *(*batfunc1)(BAT *, const ValRecord *, BAT *),
     499             :                           BAT *(*batfunc2)(const ValRecord *, BAT *, BAT *),
     500             :                           const char *malfunc)
     501             : {
     502             :         bat bid;
     503             :         BAT *bn, *b1 = NULL, *b2 = NULL, *s1 = NULL, *s2 = NULL;
     504             :         int tp1, tp2;
     505             : 
     506       40067 :         tp1 = stk->stk[getArg(pci, 1)].vtype; /* first argument */
     507       40067 :         tp2 = stk->stk[getArg(pci, 2)].vtype; /* second argument */
     508             : 
     509       40067 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
     510       40038 :                 bid = *getArgReference_bat(stk, pci, 1);
     511       40038 :                 b1 = BATdescriptor(bid);
     512       40034 :                 if (b1 == NULL)
     513           0 :                         goto bailout;
     514             :         }
     515             : 
     516       40063 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     517       38490 :                 bid = *getArgReference_bat(stk, pci, 2);
     518       38490 :                 b2 = BATdescriptor(bid);
     519       38493 :                 if (b2 == NULL)
     520           0 :                         goto bailout;
     521             :         }
     522             : 
     523       40066 :         if (pci->argc > 4) {
     524        6102 :                 assert(pci->argc == 5);
     525        6102 :                 bid = *getArgReference_bat(stk, pci, 4);
     526        6102 :                 if (!is_bat_nil(bid)) {
     527        3308 :                         s2 = BATdescriptor(bid);
     528        3308 :                         if (s2 == NULL)
     529           0 :                                 goto bailout;
     530             :                 }
     531             :         }
     532       40066 :         if (pci->argc > 3) {
     533        6195 :                 bid = *getArgReference_bat(stk, pci, 3);
     534        6195 :                 if (!is_bat_nil(bid)) {
     535        2429 :                         s1 = BATdescriptor(bid);
     536        2429 :                         if (s1 == NULL)
     537           0 :                                 goto bailout;
     538        2429 :                         if (b1 == NULL) {
     539             :                                 s2 = s1;
     540             :                                 s1 = NULL;
     541             :                         }
     542             :                 }
     543             :         }
     544             : 
     545       40066 :         if (b1 && b2)
     546       38464 :                 bn = (*batfunc)(b1, b2, s1, s2);
     547        1602 :         else if (b1)
     548        1573 :                 bn = (*batfunc1)(b1, &stk->stk[getArg(pci, 2)], s1);
     549          29 :         else if (b2)
     550          29 :                 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b2, s2);
     551             :         else
     552           0 :                 goto bailout;                   /* cannot happen */
     553       40065 :         if (b1)
     554       40036 :                 BBPunfix(b1->batCacheid);
     555       40064 :         if (b2)
     556       38491 :                 BBPunfix(b2->batCacheid);
     557       40065 :         if (s1)
     558        2429 :                 BBPunfix(s1->batCacheid);
     559       40065 :         if (s2)
     560        3308 :                 BBPunfix(s2->batCacheid);
     561       40066 :         if (bn == NULL)
     562           0 :                 return mythrow(MAL, malfunc, GDK_EXCEPTION);
     563       40066 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     564       40066 :         BBPkeepref(bn->batCacheid);
     565       40066 :         return MAL_SUCCEED;
     566             : 
     567           0 : bailout:
     568           0 :         if (b1)
     569           0 :                 BBPunfix(b1->batCacheid);
     570           0 :         if (b2)
     571           0 :                 BBPunfix(b2->batCacheid);
     572             : /* cannot happen
     573             :         if (s1)
     574             :                 BBPunfix(s1->batCacheid);
     575             : */
     576           0 :         if (s2)
     577           0 :                 BBPunfix(s2->batCacheid);
     578           0 :         throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     579             : }
     580             : 
     581             : static str
     582         368 : CMDbatMIN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     583             : {
     584             :         (void) cntxt;
     585             :         (void) mb;
     586             : 
     587         368 :         return CMDbatBINARY0(stk, pci, BATcalcmin, BATcalcmincst, BATcalccstmin, "batcalc.min");
     588             : }
     589             : 
     590             : static str
     591           0 : CMDbatMIN_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     592             : {
     593             :         (void) cntxt;
     594             :         (void) mb;
     595             : 
     596           0 :         return CMDbatBINARY0(stk, pci, BATcalcmin_no_nil, BATcalcmincst_no_nil, BATcalccstmin_no_nil, "batcalc.min_no_nil");
     597             : }
     598             : 
     599             : static str
     600           2 : CMDbatMAX(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     601             : {
     602             :         (void) cntxt;
     603             :         (void) mb;
     604             : 
     605           2 :         return CMDbatBINARY0(stk, pci, BATcalcmax, BATcalcmaxcst, BATcalccstmax, "batcalc.max");
     606             : }
     607             : 
     608             : static str
     609           4 : CMDbatMAX_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     610             : {
     611             :         (void) cntxt;
     612             :         (void) mb;
     613             : 
     614           4 :         return CMDbatBINARY0(stk, pci, BATcalcmax_no_nil, BATcalcmaxcst_no_nil, BATcalccstmax_no_nil, "batcalc.max_no_nil");
     615             : }
     616             : 
     617             : static str
     618        2648 : CMDbatADD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     619             : {
     620             :         (void) cntxt;
     621             : 
     622        2648 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     623             :                                                  calctype, 0, "batcalc.add_noerror");
     624             : }
     625             : 
     626             : static str
     627       72302 : CMDbatADDsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     628             : {
     629             :         (void) cntxt;
     630             : 
     631       72302 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     632             :                                                  calctype, 1, "batcalc.+");
     633             : }
     634             : 
     635             : static str
     636           0 : CMDbatADDenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     637             : {
     638             :         (void) cntxt;
     639             : 
     640           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
     641             :                                                  calctypeenlarge, 1, "batcalc.add_enlarge");
     642             : }
     643             : 
     644             : static str
     645           0 : CMDbatSUB(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     646             : {
     647             :         (void) cntxt;
     648             : 
     649           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     650             :                                                  calctype, 0, "batcalc.sub_noerror");
     651             : }
     652             : 
     653             : static str
     654       27902 : CMDbatSUBsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     655             : {
     656             :         (void) cntxt;
     657             : 
     658       27902 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     659             :                                                  calctype, 1, "batcalc.-");
     660             : }
     661             : 
     662             : static str
     663           0 : CMDbatSUBenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     664             : {
     665             :         (void) cntxt;
     666             : 
     667           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
     668             :                                                  calctypeenlarge, 1, "batcalc.sub_enlarge");
     669             : }
     670             : 
     671             : static str
     672           0 : CMDbatMUL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     673             : {
     674             :         (void) cntxt;
     675             : 
     676           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     677             :                                                  calctype, 0, "batcalc.mul_noerror");
     678             : }
     679             : 
     680             : static str
     681        1526 : CMDbatMULsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     682             : {
     683             :         (void) cntxt;
     684             : 
     685        1526 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     686             :                                                  calctype, 1, "batcalc.*");
     687             : }
     688             : 
     689             : static str
     690       22171 : CMDbatMULenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     691             : {
     692             :         (void) cntxt;
     693             : 
     694       22171 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
     695             :                                                  calctypeenlarge, 1, "batcalc.mul_enlarge");
     696             : }
     697             : 
     698             : static str
     699           0 : CMDbatDIV(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     700             : {
     701             :         (void) cntxt;
     702             : 
     703           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
     704             :                                                  calcdivtype, 0, "batcalc.div_noerror");
     705             : }
     706             : 
     707             : static str
     708        3473 : CMDbatDIVsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     709             : {
     710             :         (void) cntxt;
     711             : 
     712        3473 :         return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
     713             :                                                  calcdivtype, 1, "batcalc./");
     714             : }
     715             : 
     716             : static str
     717           0 : CMDbatMOD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     718             : {
     719             :         (void) cntxt;
     720             : 
     721           0 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
     722             :                                                  calcmodtype, 0, "batcalc.mod_noerror");
     723             : }
     724             : 
     725             : static str
     726         645 : CMDbatMODsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     727             : {
     728             :         (void) cntxt;
     729             : 
     730         645 :         return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
     731             :                                                  calcmodtype, 1, "batcalc.%");
     732             : }
     733             : 
     734             : static str
     735           1 : CMDbatXOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     736             : {
     737             :         (void) cntxt;
     738             :         (void) mb;
     739             : 
     740           1 :         return CMDbatBINARY0(stk, pci, BATcalcxor, BATcalcxorcst, BATcalccstxor,
     741             :                                                  "batcalc.xor");
     742             : }
     743             : 
     744             : static str
     745        1017 : CMDbatOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     746             : {
     747             :         (void) cntxt;
     748             :         (void) mb;
     749             : 
     750        1017 :         return CMDbatBINARY0(stk, pci, BATcalcor, BATcalcorcst, BATcalccstor,
     751             :                                                  "batcalc.or");
     752             : }
     753             : 
     754             : static str
     755        1730 : CMDbatAND(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     756             : {
     757             :         (void) cntxt;
     758             :         (void) mb;
     759             : 
     760        1730 :         return CMDbatBINARY0(stk, pci, BATcalcand, BATcalcandcst, BATcalccstand,
     761             :                                                  "batcalc.and");
     762             : }
     763             : 
     764             : static str
     765           0 : CMDbatLSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     766             : {
     767             :         (void) cntxt;
     768             :         (void) mb;
     769             : 
     770           0 :         return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
     771             :                                                  false, "batcalc.lsh_noerror");
     772             : }
     773             : 
     774             : static str
     775           0 : CMDbatLSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     776             : {
     777             :         (void) cntxt;
     778             :         (void) mb;
     779             : 
     780           0 :         return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
     781             :                                                  true, "batcalc.<<");
     782             : }
     783             : 
     784             : static str
     785           0 : CMDbatRSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     786             : {
     787             :         (void) cntxt;
     788             :         (void) mb;
     789             : 
     790           0 :         return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
     791             :                                                  false, "batcalc.rsh_noerror");
     792             : }
     793             : 
     794             : static str
     795         204 : CMDbatRSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     796             : {
     797             :         (void) cntxt;
     798             :         (void) mb;
     799             : 
     800         204 :         return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
     801             :                                                  true, "batcalc.>>");
     802             : }
     803             : 
     804             : static str
     805       12313 : CMDbatLT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     806             : {
     807             :         (void) cntxt;
     808             :         (void) mb;
     809             : 
     810       12313 :         return CMDbatBINARY0(stk, pci, BATcalclt, BATcalcltcst, BATcalccstlt,
     811             :                                                  "batcalc.<");
     812             : }
     813             : 
     814             : static str
     815        5415 : CMDbatLE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     816             : {
     817             :         (void) cntxt;
     818             :         (void) mb;
     819             : 
     820        5415 :         return CMDbatBINARY0(stk, pci, BATcalcle, BATcalclecst, BATcalccstle,
     821             :                                                  "batcalc.<=");
     822             : }
     823             : 
     824             : static str
     825       16192 : CMDbatGT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     826             : {
     827             :         (void) cntxt;
     828             :         (void) mb;
     829             : 
     830       16192 :         return CMDbatBINARY0(stk, pci, BATcalcgt, BATcalcgtcst, BATcalccstgt,
     831             :                                                  "batcalc.>");
     832             : }
     833             : 
     834             : static str
     835        3025 : CMDbatGE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     836             : {
     837             :         (void) cntxt;
     838             :         (void) mb;
     839             : 
     840        3025 :         return CMDbatBINARY0(stk, pci, BATcalcge, BATcalcgecst, BATcalccstge,
     841             :                                                  "batcalc.>=");
     842             : }
     843             : 
     844             : static str
     845       45598 : CMDbatEQ(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     846             : {
     847             :         (void) cntxt;
     848             :         (void) mb;
     849             : 
     850       45598 :         return CMDbatBINARY1(stk, pci, BATcalceq, BATcalceqcst, BATcalccsteq,
     851             :                                                  false, "batcalc.==");
     852             : }
     853             : 
     854             : static str
     855         749 : CMDbatNE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     856             : {
     857             :         (void) cntxt;
     858             :         (void) mb;
     859             : 
     860         749 :         return CMDbatBINARY1(stk, pci, BATcalcne, BATcalcnecst, BATcalccstne,
     861             :                                                  false, "batcalc.!=");
     862             : }
     863             : 
     864             : static str
     865           0 : CMDbatCMP(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     866             : {
     867             :         (void) cntxt;
     868             :         (void) mb;
     869             : 
     870           0 :         return CMDbatBINARY0(stk, pci, BATcalccmp, BATcalccmpcst, BATcalccstcmp,
     871             :                                                  "batcalc.cmp");
     872             : }
     873             : 
     874             : static str
     875       13224 : CMDbatBETWEEN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     876             : {
     877             :         bat bid;
     878             :         BAT *bn, *b = NULL, *lo = NULL, *hi = NULL, *s = NULL, *slo = NULL, *shi = NULL;
     879             :         int tp1, tp2, tp3, tp;
     880             :         int bc = 0;                                     /* number of extra BAT arguments */
     881             :         bool symmetric, linc, hinc, nils_false, anti, has_cand = false;
     882             : 
     883             :         (void) cntxt;
     884             :         (void) mb;
     885             : 
     886       13224 :         tp1 = stk->stk[getArg(pci, 1)].vtype;
     887       13224 :         tp2 = stk->stk[getArg(pci, 2)].vtype;
     888       13224 :         tp3 = stk->stk[getArg(pci, 3)].vtype;
     889       13224 :         if (tp1 != TYPE_bat && !isaBatType(tp1))
     890           0 :                 goto bailout;
     891       13224 :         bid = *getArgReference_bat(stk, pci, 1);
     892       13224 :         b = BATdescriptor(bid);
     893       13223 :         if (b == NULL)
     894           0 :                 goto bailout;
     895       13223 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
     896       13100 :                 bid = *getArgReference_bat(stk, pci, 2);
     897       13100 :                 lo = BATdescriptor(bid);
     898       13101 :                 if (lo == NULL)
     899           0 :                         goto bailout;
     900             :         }
     901       13224 :         if (tp3 == TYPE_bat || isaBatType(tp3)) {
     902       13087 :                 bid = *getArgReference_bat(stk, pci, 3);
     903       13087 :                 hi = BATdescriptor(bid);
     904       13086 :                 if (hi == NULL)
     905           0 :                         goto bailout;
     906             :         }
     907       13223 :         tp = getArgType(mb, pci, 4);
     908       13223 :         if (tp == TYPE_bat || isaBatType(tp)) {
     909        5591 :                 bid = *getArgReference_bat(stk, pci, 4);
     910             :                 has_cand = true;
     911        5591 :                 if (!is_bat_nil(bid)) {
     912         106 :                         s = BATdescriptor(bid);
     913         106 :                         if (s == NULL)
     914           0 :                                 goto bailout;
     915             :                 }
     916             :                 bc++;
     917             :         }
     918       13223 :         if (has_cand && lo) {
     919        5494 :                 tp = getArgType(mb, pci, 4 + bc);
     920        5494 :                 if (tp == TYPE_bat || isaBatType(tp)) {
     921        5494 :                         bid = *getArgReference_bat(stk, pci, 4 + bc);
     922        5494 :                         if (!is_bat_nil(bid)) {
     923         685 :                                 slo = BATdescriptor(bid);
     924         685 :                                 if (slo == NULL)
     925           0 :                                         goto bailout;
     926             :                         }
     927        5494 :                         bc++;
     928             :                 } else {
     929           0 :                         if (s == NULL) {
     930             :                                 /* apparently the extra bat was a NIL conditional
     931             :                                  * execution bat */
     932             :                                 has_cand = false;
     933             :                         } else
     934           0 :                                 goto bailout;
     935             :                 }
     936             :         }
     937       13223 :         if (has_cand && hi) {
     938        5478 :                 tp = getArgType(mb, pci, 4 + bc);
     939        5478 :                 if (tp != TYPE_bat && !isaBatType(tp))
     940           0 :                         goto bailout;
     941        5478 :                 bid = *getArgReference_bat(stk, pci, 4 + bc);
     942        5478 :                 if (!is_bat_nil(bid)) {
     943         300 :                         shi = BATdescriptor(bid);
     944         300 :                         if (shi == NULL)
     945           0 :                                 goto bailout;
     946             :                 }
     947        5478 :                 bc++;
     948             :         }
     949             : 
     950       13223 :         symmetric = *getArgReference_bit(stk, pci, bc + 4);
     951       13223 :         linc = *getArgReference_bit(stk, pci, bc + 5);
     952       13223 :         hinc = *getArgReference_bit(stk, pci, bc + 6);
     953       13223 :         nils_false = *getArgReference_bit(stk, pci, bc + 7);
     954       13223 :         anti = *getArgReference_bit(stk, pci, bc + 8);
     955             : 
     956       13223 :         if (b && lo && hi)
     957       13081 :                 bn = BATcalcbetween(b, lo, hi, s, slo, shi,
     958             :                                                         symmetric, linc, hinc, nils_false, anti);
     959         142 :         else if (b && lo)
     960          19 :                 bn = BATcalcbetweenbatcst(b, lo, &stk->stk[getArg(pci, 3)], s, slo,
     961             :                                                                   symmetric, linc, hinc, nils_false, anti);
     962         123 :         else if (b && hi)
     963           5 :                 bn = BATcalcbetweencstbat(b, &stk->stk[getArg(pci, 2)], hi, s, shi,
     964             :                                                                   symmetric, linc, hinc, nils_false, anti);
     965             :         else
     966         118 :                 bn = BATcalcbetweencstcst(b, &stk->stk[getArg(pci, 2)],
     967         118 :                                                                   &stk->stk[getArg(pci, 3)], s,
     968             :                                                                   symmetric, linc, hinc, nils_false, anti);
     969       13224 :         BBPunfix(b->batCacheid);
     970       13224 :         if (lo)
     971       13101 :                 BBPunfix(lo->batCacheid);
     972       13223 :         if (hi)
     973       13086 :                 BBPunfix(hi->batCacheid);
     974       13223 :         if (s)
     975         106 :                 BBPunfix(s->batCacheid);
     976       13223 :         if (slo)
     977         685 :                 BBPunfix(slo->batCacheid);
     978       13223 :         if (shi)
     979         300 :                 BBPunfix(shi->batCacheid);
     980       13223 :         if (bn == NULL)
     981           0 :                 return mythrow(MAL, "batcalc.between", OPERATION_FAILED);
     982       13223 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
     983       13223 :         BBPkeepref(bn->batCacheid);
     984       13224 :         return MAL_SUCCEED;
     985             : 
     986           0 :   bailout:
     987           0 :         if (b)
     988           0 :                 BBPunfix(b->batCacheid);
     989           0 :         if (lo)
     990           0 :                 BBPunfix(lo->batCacheid);
     991           0 :         if (hi)
     992           0 :                 BBPunfix(hi->batCacheid);
     993           0 :         if (s)
     994           0 :                 BBPunfix(s->batCacheid);
     995           0 :         if (slo)
     996           0 :                 BBPunfix(slo->batCacheid);
     997             : /* cannot happen
     998             :         if (shi)
     999             :                 BBPunfix(shi->batCacheid);
    1000             : */
    1001           0 :         throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1002             : }
    1003             : 
    1004             : static str
    1005        4034 : CMDcalcavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1006             : {
    1007             :         dbl avg;
    1008             :         BUN vals;
    1009             :         bat bid;
    1010             :         BAT *b, *s = NULL;
    1011             :         gdk_return ret;
    1012             :         int scale = 0;
    1013             : 
    1014             :         (void) cntxt;
    1015             :         (void) mb;
    1016             : 
    1017        4034 :         bid = *getArgReference_bat(stk, pci, pci->retc + 0);
    1018        4034 :         if ((b = BATdescriptor(bid)) == NULL)
    1019           0 :                 throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1020        4034 :         if ((pci->argc == pci->retc + 2 &&
    1021           0 :                  stk->stk[pci->argv[pci->retc + 1]].vtype == TYPE_bat) ||
    1022        4034 :                 pci->argc == pci->retc + 3) {
    1023           0 :                 bid = *getArgReference_bat(stk, pci, pci->retc + 1);
    1024           0 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1025           0 :                         BBPunfix(b->batCacheid);
    1026           0 :                         throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1027             :                 }
    1028             :         }
    1029        4034 :         if (pci->argc >= pci->retc + 2 &&
    1030           0 :                 stk->stk[pci->argv[pci->argc - 1]].vtype == TYPE_int) {
    1031           0 :                 scale = *getArgReference_int(stk, pci, pci->argc - 1);
    1032             :         }
    1033        4034 :         ret = BATcalcavg(b, s, &avg, &vals, scale);
    1034        4034 :         BBPunfix(b->batCacheid);
    1035        4034 :         if (s)
    1036           0 :                 BBPunfix(s->batCacheid);
    1037        4034 :         if (ret != GDK_SUCCEED)
    1038           0 :                 return mythrow(MAL, "aggr.avg", OPERATION_FAILED);
    1039        4034 :         * getArgReference_dbl(stk, pci, 0) = avg;
    1040        4034 :         if (pci->retc == 2)
    1041        3991 :                 * getArgReference_lng(stk, pci, 1) = vals;
    1042             :         return MAL_SUCCEED;
    1043             : }
    1044             : 
    1045             : static str
    1046      172649 : CMDconvertbat(MalStkPtr stk, InstrPtr pci, int tp, bool abort_on_error)
    1047             : {
    1048             :         bat bid;
    1049             :         BAT *b, *bn, *s = NULL;
    1050             : 
    1051      172649 :         bid = *getArgReference_bat(stk, pci, 1);
    1052      172649 :         if ((b = BATdescriptor(bid)) == NULL)
    1053           0 :                 throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1054      172616 :         if (pci->argc == 3) {
    1055      171524 :                 bid = *getArgReference_bat(stk, pci, 2);
    1056      171524 :                 if (!is_bat_nil(bid) && (s = BATdescriptor(bid)) == NULL) {
    1057           0 :                         BBPunfix(b->batCacheid);
    1058           0 :                         throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1059             :                 }
    1060       57914 :                 if (s && ATOMtype(s->ttype) != TYPE_oid) {
    1061           0 :                         BBPunfix(b->batCacheid);
    1062             :                         if (s)
    1063           0 :                                 BBPunfix(s->batCacheid);
    1064           0 :                         throw(MAL, "batcalc.convert", SQLSTATE(42000) ILLEGAL_ARGUMENT);
    1065             :                 }
    1066             :         }
    1067             : 
    1068      172628 :         bn = BATconvert(b, s, tp, abort_on_error, 0, 0, 0);
    1069      172639 :         BBPunfix(b->batCacheid);
    1070      172628 :         if (s)
    1071       57915 :                 BBPunfix(s->batCacheid);
    1072      172626 :         if (bn == NULL) {
    1073             :                 char buf[20];
    1074           7 :                 snprintf(buf, sizeof(buf), "batcalc.%s", ATOMname(tp));
    1075           7 :                 return mythrow(MAL, buf, OPERATION_FAILED);
    1076             :         }
    1077      172619 :         *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
    1078      172619 :         BBPkeepref(bn->batCacheid);
    1079      172617 :         return MAL_SUCCEED;
    1080             : }
    1081             : 
    1082             : static str
    1083           1 : CMDconvert_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1084             : {
    1085             :         (void) cntxt;
    1086             :         (void) mb;
    1087             : 
    1088           1 :         return CMDconvertbat(stk, pci, TYPE_bit, false);
    1089             : }
    1090             : 
    1091             : static str
    1092          31 : CMDconvertsignal_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1093             : {
    1094             :         (void) cntxt;
    1095             :         (void) mb;
    1096             : 
    1097          31 :         return CMDconvertbat(stk, pci, TYPE_bit, true);
    1098             : }
    1099             : 
    1100             : static str
    1101           0 : CMDconvert_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1102             : {
    1103             :         (void) cntxt;
    1104             :         (void) mb;
    1105             : 
    1106           0 :         return CMDconvertbat(stk, pci, TYPE_bte, false);
    1107             : }
    1108             : 
    1109             : static str
    1110         129 : CMDconvertsignal_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1111             : {
    1112             :         (void) cntxt;
    1113             :         (void) mb;
    1114             : 
    1115         129 :         return CMDconvertbat(stk, pci, TYPE_bte, true);
    1116             : }
    1117             : 
    1118             : static str
    1119           0 : CMDconvert_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1120             : {
    1121             :         (void) cntxt;
    1122             :         (void) mb;
    1123             : 
    1124           0 :         return CMDconvertbat(stk, pci, TYPE_sht, false);
    1125             : }
    1126             : 
    1127             : static str
    1128       11137 : CMDconvertsignal_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1129             : {
    1130             :         (void) cntxt;
    1131             :         (void) mb;
    1132             : 
    1133       11137 :         return CMDconvertbat(stk, pci, TYPE_sht, true);
    1134             : }
    1135             : 
    1136             : static str
    1137           0 : CMDconvert_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1138             : {
    1139             :         (void) cntxt;
    1140             :         (void) mb;
    1141             : 
    1142           0 :         return CMDconvertbat(stk, pci, TYPE_int, false);
    1143             : }
    1144             : 
    1145             : static str
    1146       37616 : CMDconvertsignal_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1147             : {
    1148             :         (void) cntxt;
    1149             :         (void) mb;
    1150             : 
    1151       37616 :         return CMDconvertbat(stk, pci, TYPE_int, true);
    1152             : }
    1153             : 
    1154             : static str
    1155           0 : CMDconvert_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1156             : {
    1157             :         (void) cntxt;
    1158             :         (void) mb;
    1159             : 
    1160           0 :         return CMDconvertbat(stk, pci, TYPE_lng, false);
    1161             : }
    1162             : 
    1163             : static str
    1164       85207 : CMDconvertsignal_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1165             : {
    1166             :         (void) cntxt;
    1167             :         (void) mb;
    1168             : 
    1169       85207 :         return CMDconvertbat(stk, pci, TYPE_lng, true);
    1170             : }
    1171             : 
    1172             : #ifdef HAVE_HGE
    1173             : 
    1174             : static str
    1175           0 : CMDconvert_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1176             : {
    1177             :         (void) cntxt;
    1178             :         (void) mb;
    1179             : 
    1180           0 :         return CMDconvertbat(stk, pci, TYPE_hge, false);
    1181             : }
    1182             : 
    1183             : static str
    1184       35763 : CMDconvertsignal_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1185             : {
    1186             :         (void) cntxt;
    1187             :         (void) mb;
    1188             : 
    1189       35763 :         return CMDconvertbat(stk, pci, TYPE_hge, true);
    1190             : }
    1191             : #endif
    1192             : 
    1193             : static str
    1194           0 : CMDconvert_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1195             : {
    1196             :         (void) cntxt;
    1197             :         (void) mb;
    1198             : 
    1199           0 :         return CMDconvertbat(stk, pci, TYPE_flt, false);
    1200             : }
    1201             : 
    1202             : static str
    1203         143 : CMDconvertsignal_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1204             : {
    1205             :         (void) cntxt;
    1206             :         (void) mb;
    1207             : 
    1208         143 :         return CMDconvertbat(stk, pci, TYPE_flt, true);
    1209             : }
    1210             : 
    1211             : static str
    1212           0 : CMDconvert_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1213             : {
    1214             :         (void) cntxt;
    1215             :         (void) mb;
    1216             : 
    1217           0 :         return CMDconvertbat(stk, pci, TYPE_dbl, false);
    1218             : }
    1219             : 
    1220             : static str
    1221        2337 : CMDconvertsignal_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1222             : {
    1223             :         (void) cntxt;
    1224             :         (void) mb;
    1225             : 
    1226        2337 :         return CMDconvertbat(stk, pci, TYPE_dbl, true);
    1227             : }
    1228             : 
    1229             : static str
    1230           0 : CMDconvert_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1231             : {
    1232             :         (void) cntxt;
    1233             :         (void) mb;
    1234             : 
    1235           0 :         return CMDconvertbat(stk, pci, TYPE_oid, false);
    1236             : }
    1237             : 
    1238             : static str
    1239          13 : CMDconvertsignal_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1240             : {
    1241             :         (void) cntxt;
    1242             :         (void) mb;
    1243             : 
    1244          13 :         return CMDconvertbat(stk, pci, TYPE_oid, true);
    1245             : }
    1246             : 
    1247             : static str
    1248           0 : CMDconvert_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1249             : {
    1250             :         (void) cntxt;
    1251             :         (void) mb;
    1252             : 
    1253           0 :         return CMDconvertbat(stk, pci, TYPE_str, false);
    1254             : }
    1255             : 
    1256             : static str
    1257         272 : CMDconvertsignal_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1258             : {
    1259             :         (void) cntxt;
    1260             :         (void) mb;
    1261             : 
    1262         272 :         return CMDconvertbat(stk, pci, TYPE_str, true);
    1263             : }
    1264             : 
    1265             : static str
    1266        2616 : CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
    1267             : {
    1268             :         BAT *b = NULL, *b1 = NULL, *b2 = NULL, *bn;
    1269             :         int tp0, tp1, tp2;
    1270             :         bat *ret;
    1271             :         BUN cnt = BUN_NONE;
    1272             : 
    1273             :         (void) cntxt;
    1274             :         (void) mb;
    1275             : 
    1276        2616 :         if (pci->argc != 4)
    1277           0 :                 throw(MAL, "batcalc.ifthen", "Operation not supported.");
    1278             : 
    1279        2616 :         ret = getArgReference_bat(stk, pci, 0);
    1280        2616 :         tp0 = stk->stk[getArg(pci, 1)].vtype;
    1281        2616 :         tp1 = stk->stk[getArg(pci, 2)].vtype;
    1282        2616 :         tp2 = stk->stk[getArg(pci, 3)].vtype;
    1283        2616 :         if (tp0 == TYPE_bat || isaBatType(tp0)) {
    1284        2616 :                 b = BATdescriptor(* getArgReference_bat(stk, pci, 1));
    1285        2616 :                 if (b == NULL)
    1286           0 :                         throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1287        2616 :                 cnt = BATcount(b);
    1288             :         }
    1289        2616 :         if (tp1 == TYPE_bat || isaBatType(tp1)) {
    1290          25 :                 b1 = BATdescriptor(* getArgReference_bat(stk, pci, 2));
    1291          25 :                 if (b1 == NULL) {
    1292           0 :                         if (b)
    1293           0 :                                 BBPunfix(b->batCacheid);
    1294           0 :                         throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1295             :                 }
    1296          25 :                 if (cnt == BUN_NONE)
    1297           0 :                         cnt = BATcount(b1);
    1298          25 :                 else if (BATcount(b1) != cnt) {
    1299           0 :                         BBPunfix(b->batCacheid);
    1300           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1301             :                 }
    1302             :         }
    1303        2616 :         if (tp2 == TYPE_bat || isaBatType(tp2)) {
    1304        2258 :                 b2 = BATdescriptor(* getArgReference_bat(stk, pci, 3));
    1305        2258 :                 if (b2 == NULL) {
    1306           0 :                         if (b)
    1307           0 :                                 BBPunfix(b->batCacheid);
    1308           0 :                         if (b1)
    1309           0 :                                 BBPunfix(b1->batCacheid);
    1310           0 :                         throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1311             :                 }
    1312        2258 :                 if (cnt == BUN_NONE)
    1313             :                         cnt = BATcount(b2);
    1314        2258 :                 else if (BATcount(b2) != cnt) {
    1315           0 :                         if (b)
    1316           0 :                                 BBPunfix(b->batCacheid);
    1317           0 :                         if (b1)
    1318           0 :                                 BBPunfix(b1->batCacheid);
    1319           0 :                         throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1320             :                 }
    1321             :         }
    1322        2616 :         if (b == NULL && b1 == NULL && b2 == NULL) {
    1323             :                 /* at least one BAT required */
    1324           0 :                 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
    1325             :         }
    1326        2616 :         if (b != NULL) {
    1327        2616 :                 if (b1 != NULL) {
    1328          25 :                         if (b2 != NULL) {
    1329          17 :                                 bn = BATcalcifthenelse(b, b1, b2);
    1330             :                         } else {
    1331           8 :                                 bn = BATcalcifthenelsecst(b, b1, &stk->stk[getArg(pci, 3)]);
    1332             :                         }
    1333             :                 } else {
    1334        2591 :                         if (b2 != NULL) {
    1335        2241 :                                 bn = BATcalcifthencstelse(b, &stk->stk[getArg(pci, 2)], b2);
    1336             :                         } else {
    1337         350 :                                 bn = BATcalcifthencstelsecst(b, &stk->stk[getArg(pci, 2)], &stk->stk[getArg(pci, 3)]);
    1338             :                         }
    1339             :                 }
    1340             :         } else {
    1341             :                 bit v;
    1342           0 :                 if (tp0 == TYPE_msk)
    1343           0 :                         v = (bit) *getArgReference_msk(stk, pci, 1);
    1344             :                 else
    1345           0 :                         v = *getArgReference_bit(stk, pci, 1);
    1346           0 :                 if (is_bit_nil(v)) {
    1347           0 :                         if (b1 != NULL)
    1348           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype, ATOMnilptr(b1->ttype), BATcount(b1), TRANSIENT);
    1349             :                         else
    1350           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype, ATOMnilptr(b2->ttype), BATcount(b2), TRANSIENT);
    1351           0 :                 } else if (v) {
    1352           0 :                         if (b1 != NULL)
    1353           0 :                                 bn = COLcopy(b1, b1->ttype, false, TRANSIENT);
    1354             :                         else
    1355           0 :                                 bn = BATconstant(b2->hseqbase, b2->ttype, VALptr(&stk->stk[getArg(pci, 2)]), BATcount(b2), TRANSIENT);
    1356             :                 } else {
    1357           0 :                         if (b2 != NULL)
    1358           0 :                                 bn = COLcopy(b2, b2->ttype, false, TRANSIENT);
    1359             :                         else
    1360           0 :                                 bn = BATconstant(b1->hseqbase, b1->ttype, VALptr(&stk->stk[getArg(pci, 3)]), BATcount(b1), TRANSIENT);
    1361             :                 }
    1362             :         }
    1363        2616 :         if (b)
    1364        2616 :                 BBPunfix(b->batCacheid);
    1365        2616 :         if (b1)
    1366          25 :                 BBPunfix(b1->batCacheid);
    1367        2616 :         if (b2)
    1368        2258 :                 BBPunfix(b2->batCacheid);
    1369        2616 :         if (bn == NULL) {
    1370           0 :                 return mythrow(MAL, "batcalc.ifthenelse", OPERATION_FAILED);
    1371             :         }
    1372        2616 :         BBPkeepref(*ret = bn->batCacheid);
    1373        2616 :         return MAL_SUCCEED;
    1374             : }
    1375             : 
    1376             : #include "mel.h"
    1377             : 
    1378             : static str
    1379         264 : batcalc_init(void)
    1380             : {
    1381             :         int types[16], cur = 0, *tp;
    1382             :         int specials[4];
    1383             :         int *integer, *floats, *extra;
    1384             : 
    1385         264 :         types[cur++] = TYPE_bit;
    1386             :         integer = types+cur;
    1387         264 :         types[cur++] = TYPE_bte;
    1388         264 :         types[cur++] = TYPE_sht;
    1389         264 :         types[cur++] = TYPE_int;
    1390         264 :         types[cur++] = TYPE_lng;
    1391             : #ifdef HAVE_HGE
    1392         264 :         types[cur++] = TYPE_hge;
    1393             : #endif
    1394             :         floats = types+cur;
    1395         264 :         types[cur++] = TYPE_flt;
    1396         264 :         types[cur++] = TYPE_dbl;
    1397             :         extra = types+cur;
    1398         264 :         types[cur++] = TYPE_oid;
    1399         264 :         types[cur++] = TYPE_str;
    1400             : 
    1401             :         cur = 0;
    1402         264 :         specials[cur++] = TYPE_bit;
    1403         264 :         specials[cur++] = TYPE_oid;
    1404         264 :         specials[cur++] = TYPE_str;
    1405             : 
    1406         264 :         mel_func_arg cand = { .type = TYPE_oid, .isbat=1 };
    1407             : 
    1408             :         int err=0;
    1409             :         /* for all numeric types, use reverse order */
    1410        2112 :         for(tp = integer; tp < extra && !err; tp++) {
    1411        1848 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat=1 };
    1412        1848 :                 mel_func_arg arg = { .type = *tp, .isbat=1 };
    1413             : 
    1414        1848 :                 err += melFunction(false, "batcalc", "iszero", (fptr)&CMDbatISZERO, "CMDbatISZERO", false, "Unary check for zero over the tail of the bat", 1, 2, ret, arg);
    1415        1848 :                 err += melFunction(false, "batcalc", "iszero", (fptr)&CMDbatISZERO, "CMDbatISZERO", false, "Unary check for zero over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1416             :         }
    1417        2376 :         for(tp = types; tp < extra && !err; tp++) { /* bit + numeric */
    1418        2112 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1419        2112 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1420             : 
    1421        2112 :                 err += melFunction(false, "batcalc", "not", (fptr)&CMDbatNOT, "CMDbatNOT", false, "Unary bitwise not over the tail of the bat", 1, 2, ret, arg);
    1422        2112 :                 err += melFunction(false, "batcalc", "not", (fptr)&CMDbatNOT, "CMDbatNOT", false, "Unary bitwise not over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1423             :         }
    1424        2112 :         for(tp = integer; tp < extra && !err; tp++) {
    1425        1848 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1426        1848 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1427             : 
    1428        1848 :                 err += melFunction(false, "batcalc", "sign", (fptr)&CMDbatSIGN, "CMDbatSIGN", false, "Unary sign (-1,0,1) over the tail of the bat", 1, 2, ret, arg);
    1429        1848 :                 err += melFunction(false, "batcalc", "sign", (fptr)&CMDbatSIGN, "CMDbatSIGN", false, "Unary sign (-1,0,1) over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1430             :         }
    1431        2112 :         for(tp = integer; tp < extra && !err; tp++) {
    1432        1848 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1433        1848 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1434             : 
    1435        1848 :                 err += melFunction(false, "batcalc", "abs", (fptr)&CMDbatABS, "CMDbatABS", false, "Unary abs over the tail of the bat", 1, 2, ret, arg);
    1436        1848 :                 err += melFunction(false, "batcalc", "abs", (fptr)&CMDbatABS, "CMDbatABS", false, "Unary abs over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1437             : 
    1438        1848 :                 err += melFunction(false, "batcalc", "-", (fptr)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat", 1, 2, ret, arg);
    1439        1848 :                 err += melFunction(false, "batcalc", "-", (fptr)&CMDbatNEG, "CMDbatNEG", false, "Unary neg over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1440             : 
    1441        1848 :                 err += melFunction(false, "batcalc", "++", (fptr)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat", 1, 2, ret, arg);
    1442        1848 :                 err += melFunction(false, "batcalc", "++", (fptr)&CMDbatINCR, "CMDbatINCR", false, "Unary increment over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1443             : 
    1444        1848 :                 err += melFunction(false, "batcalc", "--", (fptr)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat", 1, 2, ret, arg);
    1445        1848 :                 err += melFunction(false, "batcalc", "--", (fptr)&CMDbatDECR, "CMDbatDECR", false, "Unary decrement over the tail of the bat with candidates list", 1, 3, ret, arg, cand);
    1446             :         }
    1447             :         /* possibly add the min/max + _no_nil */
    1448             :         /* binops on numeric types */
    1449             :         struct {
    1450             :            char *op;
    1451             :            char *op_ne;
    1452             :            char *fname;
    1453             :            char *fname_ne;
    1454             :            char *fname_el;
    1455             :            fptr fcn;
    1456             :            fptr fcn_ne;
    1457             :            fptr fcn_el;
    1458             :            char *comment;
    1459             :            char *comment_ne;
    1460             :            char *comment_v;
    1461             :            char *comment_v_ne;
    1462             :            char *comment_v_;
    1463             :            char *comment_v__ne;
    1464             :            char *comment_el;
    1465             :            char *comment_el_v;
    1466             :            char *comment_el_v_;
    1467         264 :         } funcs[3] = {
    1468             :           {
    1469             :                 .op = "+",
    1470             :                 .fcn = (fptr)CMDbatADDsignal,
    1471             :                 .fname = "CMDbatADDsignal",
    1472             :                 .op_ne = "add_noerror",
    1473             :                 .fcn_ne = (fptr)&CMDbatADD,
    1474             :                 .fname_ne = "CMDbatADD",
    1475             :                 .fcn_el = (fptr)&CMDbatADDenlarge,
    1476             :                 .fname_el = "CMDbatADDenlarge",
    1477             :                 .comment = "Return B1 + B2 with candidates list, signal error on overflow",
    1478             :                 .comment_ne = "Return B1 + B2 with candidates list, overflow causes NIL value",
    1479             :                 .comment_v = "Return B + V with candidates list, signal error on overflow",
    1480             :                 .comment_v_ne = "Return B + V with candidates list, overflow causes NIL value",
    1481             :                 .comment_v_ = "Return V + B with candidates list, signal error on overflow",
    1482             :                 .comment_v__ne = "Return V + B with candidates list, overflow causes NIL value",
    1483             :                 .comment_el = "Return B1 + B2 with candidates list, guarantee no overflow by returning larger type",
    1484             :                 .comment_el_v = "Return B + V with candidates list, guarantee no overflow by returning larger type",
    1485             :                 .comment_el_v_ = "Return V + B with candidates list, guarantee no overflow by returning larger type",
    1486             :           }, {
    1487             :                 .op = "-",
    1488             :                 .fcn = (fptr)CMDbatSUBsignal,
    1489             :                 .fname = "CMDbatSUBsignal",
    1490             :                 .op_ne = "sub_noerror",
    1491             :                 .fcn_ne = (fptr)&CMDbatSUB,
    1492             :                 .fname_ne = "CMDbatSUB",
    1493             :                 .fcn_el = (fptr)&CMDbatSUBenlarge,
    1494             :                 .fname_el = "CMDbatSUBenlarge",
    1495             :                 .comment = "Return B1 - B2 with candidates list, signal error on overflow",
    1496             :                 .comment_ne = "Return B1 - B2 with candidates list, overflow causes NIL value",
    1497             :                 .comment_v = "Return B - V with candidates list, signal error on overflow",
    1498             :                 .comment_v_ne = "Return B - V with candidates list, overflow causes NIL value",
    1499             :                 .comment_v_ = "Return V - B with candidates list, signal error on overflow",
    1500             :                 .comment_v__ne = "Return V - B with candidates list, overflow causes NIL value",
    1501             :                 .comment_el = "Return B1 - B2 with candidates list, guarantee no overflow by returning larger type",
    1502             :                 .comment_el_v = "Return B - V with candidates list, guarantee no overflow by returning larger type",
    1503             :                 .comment_el_v_ = "Return V - B with candidates list, guarantee no overflow by returning larger type",
    1504             :           }, {
    1505             :                 .op = "*",
    1506             :                 .fcn = (fptr)CMDbatMULsignal,
    1507             :                 .fname = "CMDbatMULsignal",
    1508             :                 .op_ne = "mul_noerror",
    1509             :                 .fcn_ne = (fptr)&CMDbatMUL,
    1510             :                 .fname_ne = "CMDbatMUL",
    1511             :                 .fcn_el = (fptr)&CMDbatMULenlarge,
    1512             :                 .fname_el = "CMDbatMULenlarge",
    1513             :                 .comment = "Return B1 * B2 with candidates list, signal error on overflow",
    1514             :                 .comment_ne = "Return B1 * B2 with candidates list, overflow causes NIL value",
    1515             :                 .comment_v = "Return B * V with candidates list, signal error on overflow",
    1516             :                 .comment_v_ne = "Return B * V with candidates list, overflow causes NIL value",
    1517             :                 .comment_v_ = "Return V * B with candidates list, signal error on overflow",
    1518             :                 .comment_v__ne = "Return V * B with candidates list, overflow causes NIL value",
    1519             :                 .comment_el = "Return B1 * B2 with candidates list, guarantee no overflow by returning larger type",
    1520             :                 .comment_el_v = "Return B * V with candidates list, guarantee no overflow by returning larger type",
    1521             :                 .comment_el_v_ = "Return V * B with candidates list, guarantee no overflow by returning larger type",
    1522             :           }
    1523             :         };
    1524        1056 :         for (int f=0; f<3; f++) {
    1525             :           int *tp1, *tp2, *rt;
    1526        6336 :           for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1527       44352 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1528      310464 :               for(rt = extra-1; rt >= integer && !err; rt--) {
    1529      271656 :                 if (f!=3 && (*rt < *tp1 || *rt < *tp2))
    1530      160776 :                         continue;
    1531      110880 :                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1532      110880 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1533      110880 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1534      110880 :                 mel_func_arg varg1 = { .type = *tp1 };
    1535      110880 :                 mel_func_arg varg2 = { .type = *tp2 };
    1536             : 
    1537      110880 :                 if (*rt == *tp1 || *rt == *tp2 || f==3) {
    1538       38808 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1539       38808 :                   err += melFunction(false, "batcalc", funcs[f].op_ne, funcs[f].fcn_ne, funcs[f].fname_ne, false, funcs[f].comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1540       38808 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1541       38808 :                   err += melFunction(false, "batcalc", funcs[f].op_ne, funcs[f].fcn_ne, funcs[f].fname_ne, false, funcs[f].comment_v_ne, 1, 4, ret, arg1, varg2, cand);
    1542       38808 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn, funcs[f].fname, false, funcs[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1543       38808 :                   err += melFunction(false, "batcalc", funcs[f].op_ne, funcs[f].fcn_ne, funcs[f].fname_ne, false, funcs[f].comment_v__ne, 1, 4, ret, varg1, arg2, cand);
    1544             :                 } else {
    1545       72072 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el, 1, 5, ret, arg1, arg2, cand, cand);
    1546       72072 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el_v, 1, 4, ret, arg1, varg2, cand);
    1547       72072 :                   err += melFunction(false, "batcalc", funcs[f].op, funcs[f].fcn_el, funcs[f].fname_el, false, funcs[f].comment_el_v_, 1, 4, ret, varg1, arg2, cand);
    1548             :                 }
    1549             :               }
    1550             :             }
    1551             :           }
    1552             :         }
    1553             :         {       /* multiplication between integers and floating-points, returning integers */
    1554             :                 int *tp1, *tp2, *tp3;
    1555        1584 :                 for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1556        3960 :                         for(tp2 = floats; tp2 < extra && !err; tp2++) {
    1557       15840 :                                 for(tp3 = integer; tp3 < floats && !err; tp3++) {
    1558       13200 :                                         int in1 = *tp3, in2 = *tp2;
    1559             : 
    1560       39600 :                                         for (int i = 0 ; i < 2 ; i++) {
    1561       26400 :                                                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1562       26400 :                                                 mel_func_arg arg1 = { .type = in1, .isbat =1 };
    1563       26400 :                                                 mel_func_arg arg2 = { .type = in2, .isbat =1 };
    1564       26400 :                                                 mel_func_arg varg1 = { .type = in1 };
    1565       26400 :                                                 mel_func_arg varg2 = { .type = in2 };
    1566             : 
    1567       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1568       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op_ne, funcs[2].fcn_ne, funcs[2].fname_ne, false, funcs[2].comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1569       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v, 1, 4, ret, arg1, varg2, cand);
    1570       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op_ne, funcs[2].fcn_ne, funcs[2].fname_ne, false, funcs[2].comment_v_ne, 1, 4, ret, arg1, varg2, cand);
    1571       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op, funcs[2].fcn, funcs[2].fname, false, funcs[2].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1572       26400 :                                                 err += melFunction(false, "batcalc", funcs[2].op_ne, funcs[2].fcn_ne, funcs[2].fname_ne, false, funcs[2].comment_v__ne, 1, 4, ret, varg1, arg2, cand);
    1573             : 
    1574             :                                                 /* swap variables */
    1575             :                                                 in1 ^= in2;
    1576             :                                                 in2 ^= in1;
    1577             :                                                 in1 ^= in2;
    1578             :                                         }
    1579             :                                 }
    1580             :                         }
    1581             :                 }
    1582             :         }
    1583             :         struct {
    1584             :            char *op;
    1585             :            char *op_ne;
    1586             :            char *fname;
    1587             :            char *fname_ne;
    1588             :            char *fname_el;
    1589             :            fptr fcn;
    1590             :            fptr fcn_ne;
    1591             :            fptr fcn_el;
    1592             :            char *comment;
    1593             :            char *comment_ne;
    1594             :            char *comment_v;
    1595             :            char *comment_v_ne;
    1596             :            char *comment_v_;
    1597             :            char *comment_v__ne;
    1598             :            char *comment_el;
    1599             :            char *comment_el_v;
    1600             :            char *comment_el_v_;
    1601         264 :         } div = {
    1602             :                 .op = "/",
    1603             :                 .fcn = (fptr)CMDbatDIVsignal,
    1604             :                 .fname = "CMDbatDIVsignal",
    1605             :                 .op_ne = "div_noerror",
    1606             :                 .fcn_ne = (fptr)&CMDbatDIV,
    1607             :                 .fname_ne = "CMDbatDIV",
    1608             :                 .comment = "Return B1 / B2 with candidates list, signal error on overflow",
    1609             :                 .comment_ne = "Return B1 / B2 with candidates list, overflow causes NIL value",
    1610             :                 .comment_v = "Return B / V with candidates list, signal error on overflow",
    1611             :                 .comment_v_ne = "Return B / V with candidates list, overflow causes NIL value",
    1612             :                 .comment_v_ = "Return V / B with candidates list, signal error on overflow",
    1613             :                 .comment_v__ne = "Return V / B with candidates list, overflow causes NIL value",
    1614             :         };
    1615             :         int *tp1, *tp2, *rt;
    1616        2112 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1617       14784 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1618       64680 :               for(rt = extra-1; rt >= tp1 && !err; rt--) {
    1619       51744 :                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1620       51744 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1621       51744 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1622       51744 :                 mel_func_arg varg1 = { .type = *tp1 };
    1623       51744 :                 mel_func_arg varg2 = { .type = *tp2 };
    1624             : 
    1625       51744 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1626       51744 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1627       51744 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1628       51744 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_v_ne, 1, 4, ret, arg1, varg2, cand);
    1629       51744 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1630       51744 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_v__ne, 1, 4, ret, varg1, arg2, cand);
    1631             :               }
    1632             :             }
    1633             :         }
    1634             :         /* division between integers and floating-points, returning integers */
    1635         792 :         for(tp1 = floats; tp1 < extra && !err; tp1++) {
    1636        3168 :             for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1637       15840 :               for(rt = integer; rt < floats && !err; rt++) {
    1638       13200 :                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1639       13200 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1640       13200 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1641       13200 :                 mel_func_arg varg1 = { .type = *tp1 };
    1642       13200 :                 mel_func_arg varg2 = { .type = *tp2 };
    1643             : 
    1644       13200 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1645       13200 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1646       13200 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v, 1, 4, ret, arg1, varg2, cand);
    1647       13200 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_v_ne, 1, 4, ret, arg1, varg2, cand);
    1648       13200 :                 err += melFunction(false, "batcalc", div.op, div.fcn, div.fname, false, div.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1649       13200 :                 err += melFunction(false, "batcalc", div.op_ne, div.fcn_ne, div.fname_ne, false, div.comment_v__ne, 1, 4, ret, varg1, arg2, cand);
    1650             :               }
    1651             :             }
    1652             :         }
    1653             :         struct {
    1654             :            char *op;
    1655             :            char *op_ne;
    1656             :            char *fname;
    1657             :            char *fname_ne;
    1658             :            fptr fcn;
    1659             :            fptr fcn_ne;
    1660             :            char *comment;
    1661             :            char *comment_ne;
    1662             :            char *comment_v;
    1663             :            char *comment_v_ne;
    1664             :            char *comment_v_;
    1665             :            char *comment_v__ne;
    1666             :         } mods = {
    1667             :                 .op = "%",
    1668             :                 .fcn = (fptr)CMDbatMODsignal,
    1669             :                 .fname = "CMDbatMODsignal",
    1670             :                 .op_ne = "mod_noerror",
    1671             :                 .fcn_ne = (fptr)&CMDbatMOD,
    1672             :                 .fname_ne = "CMDbatMOD",
    1673             :                 .comment = "Return B1 % B2 with candidates list, signal error on overflow",
    1674             :                 .comment_ne = "Return B1 % B2 with candidates list, overflow causes NIL value",
    1675             :                 .comment_v = "Return B % V with candidates list, signal error on overflow",
    1676             :                 .comment_v_ne = "Return B % V with candidates list, overflow causes NIL value",
    1677             :                 .comment_v_ = "Return V % B with candidates list, signal error on overflow",
    1678             :                 .comment_v__ne = "Return V % B with candidates list, overflow causes NIL value",
    1679             :         };
    1680        2112 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1681       14784 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1682      103488 :               for(rt = extra-1; rt >= integer && !err; rt--) {
    1683       90552 :                 if (rt < tp1 && rt < tp2)
    1684       64944 :                         continue;
    1685       66528 :                 if (*rt == TYPE_dbl) {
    1686       12936 :                         if (*tp1 != TYPE_dbl || *tp2 != TYPE_dbl)
    1687       12672 :                                 continue;
    1688       53592 :                 } else if (*rt == TYPE_flt) {
    1689       12672 :                         if (*tp1 != TYPE_flt || *tp2 != TYPE_flt)
    1690       12408 :                                 continue;
    1691             :                 } else {
    1692       40920 :                         if (*tp1 == TYPE_flt || *tp2 == TYPE_flt || *tp1 == TYPE_dbl || *tp2 == TYPE_dbl)
    1693       15840 :                                 continue;
    1694             :                 }
    1695       25608 :                 mel_func_arg ret = { .type = *rt, .isbat =1 };
    1696       25608 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1697       25608 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1698       25608 :                 mel_func_arg varg1 = { .type = *tp1 };
    1699       25608 :                 mel_func_arg varg2 = { .type = *tp2 };
    1700             : 
    1701       25608 :                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1702       25608 :                 err += melFunction(false, "batcalc", mods.op_ne, mods.fcn_ne, mods.fname_ne, false, mods.comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1703       25608 :                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v, 1, 4, ret, arg1, varg2, cand);
    1704       25608 :                 err += melFunction(false, "batcalc", mods.op_ne, mods.fcn_ne, mods.fname_ne, false, mods.comment_v_ne, 1, 4, ret, arg1, varg2, cand);
    1705       25608 :                 err += melFunction(false, "batcalc", mods.op, mods.fcn, mods.fname, false, mods.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1706       25608 :                 err += melFunction(false, "batcalc", mods.op_ne, mods.fcn_ne, mods.fname_ne, false, mods.comment_v__ne, 1, 4, ret, varg1, arg2, cand);
    1707             :               }
    1708             :             }
    1709             :         }
    1710             :         struct {
    1711             :            char *op;
    1712             :            char *fname;
    1713             :            fptr fcn;
    1714             :            char *comment;
    1715             :            char *comment_v;
    1716             :            char *comment_v_;
    1717         264 :         } logops[3] = {
    1718             :           {
    1719             :                 .op = "and",
    1720             :                 .fcn = (fptr)CMDbatAND,
    1721             :                 .fname = "CMDbatAND",
    1722             :                 .comment = "Return B1 and B2",
    1723             :                 .comment_v = "Return B and V",
    1724             :                 .comment_v_ = "Return V and B",
    1725             :           }, {
    1726             :                 .op = "or",
    1727             :                 .fcn = (fptr)CMDbatOR,
    1728             :                 .fname = "CMDbatOR",
    1729             :                 .comment = "Return B1 or B2",
    1730             :                 .comment_v = "Return B or V",
    1731             :                 .comment_v_ = "Return V or B",
    1732             :           }, {
    1733             :                 .op = "xor",
    1734             :                 .fcn = (fptr)CMDbatXOR,
    1735             :                 .fname = "CMDbatXOR",
    1736             :                 .comment = "Return B1 xor B2",
    1737             :                 .comment_v = "Return B xor V",
    1738             :                 .comment_v_ = "Return V xor B",
    1739             :           }
    1740             :         };
    1741        1056 :         for (int f=0; f<3; f++) {
    1742        7128 :           for(tp = types+0; tp < extra && !err; tp++) {
    1743        6336 :                 mel_func_arg ret = { .type = *tp, .isbat =1 };
    1744        6336 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    1745        6336 :                 mel_func_arg varg = { .type = *tp };
    1746             : 
    1747        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 3, ret, arg, arg);
    1748        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1749        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 3, ret, arg, varg);
    1750        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v, 1, 4, ret, arg, varg, cand);
    1751        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 3, ret, varg, arg);
    1752        6336 :                 err += melFunction(false, "batcalc", logops[f].op, logops[f].fcn, logops[f].fname, false, logops[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1753             :           }
    1754             :         }
    1755             :         struct {
    1756             :            char *op;
    1757             :            char *op_ne;
    1758             :            char *fname;
    1759             :            fptr fcn;
    1760             :            char *fname_ne;
    1761             :            fptr fcn_ne;
    1762             :            char *comment;
    1763             :            char *comment_v;
    1764             :            char *comment_v_;
    1765             :            char *comment_ne;
    1766             :            char *comment_ne_v;
    1767             :            char *comment_ne_v_;
    1768         264 :         } shifts[2] = {
    1769             :           {
    1770             :                 .op = "<<",
    1771             :                 .op_ne = "lsh_noerror",
    1772             :                 .fcn = (fptr)CMDbatLSHsignal,
    1773             :                 .fname = "CMDbatLSHsignal",
    1774             :                 .fcn_ne = (fptr)CMDbatLSH,
    1775             :                 .fname_ne = "CMDbatLSH",
    1776             :                 .comment = "Return B1 << B2, raise error on out of range second operand",
    1777             :                 .comment_v = "Return B << V, raise error on out of range second operand",
    1778             :                 .comment_v_ = "Return B << V, raise error on out of range second operand",
    1779             :                 .comment_ne = "Return B1 << B2, out of range second operand causes NIL value",
    1780             :                 .comment_ne_v = "Return B << V, out of range second operand causes NIL value",
    1781             :                 .comment_ne_v_ = "Return V << B, out of range second operand causes NIL value",
    1782             :           }, {
    1783             :                 .op = ">>",
    1784             :                 .op_ne = "rsh_noerror",
    1785             :                 .fcn = (fptr)CMDbatRSHsignal,
    1786             :                 .fname = "CMDbatRSHsignal",
    1787             :                 .fcn_ne = (fptr)CMDbatRSH,
    1788             :                 .fname_ne = "CMDbatRSH",
    1789             :                 .comment = "Return B1 >> B2, raise error on out of range second operand",
    1790             :                 .comment_v = "Return B >> V, raise error on out of range second operand",
    1791             :                 .comment_v_ = "Return B >> V, raise error on out of range second operand",
    1792             :                 .comment_ne = "Return B1 >> B2, out of range second operand causes NIL value",
    1793             :                 .comment_ne_v = "Return B >> V, out of range second operand causes NIL value",
    1794             :                 .comment_ne_v_ = "Return V >> B, out of range second operand causes NIL value",
    1795             :           }
    1796             :         };
    1797         792 :         for (int f=0; f<2; f++) {
    1798             :           int *tp1, *tp2;
    1799        3168 :           for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1800       15840 :             for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1801       13200 :                 mel_func_arg ret = { .type = *tp1, .isbat =1 };
    1802       13200 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1803       13200 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1804       13200 :                 mel_func_arg varg1 = { .type = *tp1 };
    1805       13200 :                 mel_func_arg varg2 = { .type = *tp2 };
    1806             : 
    1807       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 3, ret, arg1, arg2);
    1808       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1809       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne, 1, 3, ret, arg1, arg2);
    1810       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne, 1, 5, ret, arg1, arg2, cand, cand);
    1811       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 3, ret, arg1, varg2);
    1812       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1813       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne_v, 1, 3, ret, arg1, varg2);
    1814       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne_v, 1, 4, ret, arg1, varg2, cand);
    1815       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 3, ret, varg1, arg2);
    1816       13200 :                 err += melFunction(false, "batcalc", shifts[f].op, shifts[f].fcn, shifts[f].fname, false, shifts[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1817       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne_v_, 1, 3, ret, varg1, arg2);
    1818       13200 :                 err += melFunction(false, "batcalc", shifts[f].op_ne, shifts[f].fcn_ne, shifts[f].fname_ne, false, shifts[f].comment_ne_v_, 1, 4, ret, varg1, arg2, cand);
    1819             :             }
    1820             :           }
    1821             :         }
    1822             : 
    1823             :         struct {
    1824             :            char *op;
    1825             :            char *fname;
    1826             :            fptr fcn;
    1827             :            char *comment;
    1828             :            char *comment_v;
    1829             :            char *comment_v_;
    1830         264 :         } cmps[6] = {
    1831             :           {
    1832             :                 .op = "<",
    1833             :                 .fcn = (fptr)CMDbatLT,
    1834             :                 .fname = "CMDbatLT",
    1835             :                 .comment = "Return B1 < B2",
    1836             :                 .comment_v = "Return B < V",
    1837             :                 .comment_v_ = "Return B < V",
    1838             :           }, {
    1839             :                 .op = "<=",
    1840             :                 .fcn = (fptr)CMDbatLE,
    1841             :                 .fname = "CMDbatLE",
    1842             :                 .comment = "Return B1 <= B2",
    1843             :                 .comment_v = "Return B <= V",
    1844             :                 .comment_v_ = "Return B <= V",
    1845             :           }, {
    1846             :                 .op = ">",
    1847             :                 .fcn = (fptr)CMDbatGT,
    1848             :                 .fname = "CMDbatGT",
    1849             :                 .comment = "Return B1 > B2",
    1850             :                 .comment_v = "Return B > V",
    1851             :                 .comment_v_ = "Return B > V",
    1852             :           }, {
    1853             :                 .op = ">=",
    1854             :                 .fcn = (fptr)CMDbatGE,
    1855             :                 .fname = "CMDbatGE",
    1856             :                 .comment = "Return B1 >= B2",
    1857             :                 .comment_v = "Return B >= V",
    1858             :                 .comment_v_ = "Return B >= V",
    1859             :           }, {
    1860             :                 .op = "==",
    1861             :                 .fcn = (fptr)CMDbatEQ,
    1862             :                 .fname = "CMDbatEQ",
    1863             :                 .comment = "Return B1 == B2",
    1864             :                 .comment_v = "Return B == V",
    1865             :                 .comment_v_ = "Return B == V",
    1866             :           }, {
    1867             :                 .op = "!=",
    1868             :                 .fcn = (fptr)CMDbatNE,
    1869             :                 .fname = "CMDbatNE",
    1870             :                 .comment = "Return B1 != B2",
    1871             :                 .comment_v = "Return B != V",
    1872             :                 .comment_v_ = "Return B != V",
    1873             :           }
    1874             :         };
    1875         264 :         int newtypes[6] = { ATOMindex("json"), ATOMindex("inet"), ATOMindex("uuid"), TYPE_date, TYPE_daytime, TYPE_timestamp };
    1876        1848 :         for (int f=0; f<6; f++) {
    1877        1584 :           mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1878        1584 :           mel_func_arg arg = { .type = TYPE_any, .isbat =1, .nr=1 };
    1879        1584 :           mel_func_arg varg = { .type = TYPE_any, .nr=1 };
    1880             : 
    1881        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1882        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1883        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1884        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1885        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1886        1584 :           err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1887             : 
    1888        1584 :           if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1889         528 :                 mel_func_arg nil_matches = { .type = TYPE_bit };
    1890             : 
    1891         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1892         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg, arg, cand, cand, nil_matches);
    1893         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, nil_matches);
    1894         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg, varg, cand, nil_matches);
    1895         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, nil_matches);
    1896         528 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg, arg, cand, nil_matches);
    1897             :           }
    1898             : 
    1899             :           /* uuid, json, inet and mtime (date, daytime, timestamp) */
    1900       11088 :           for (int nt = 0; nt < 6; nt++) {
    1901        9504 :              mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1902        9504 :              mel_func_arg arg = { .type = newtypes[nt], .isbat =1, .nr=1 };
    1903        9504 :              mel_func_arg varg = { .type = newtypes[nt], .nr=1 };
    1904             : 
    1905        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg, arg);
    1906        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg, arg, cand, cand);
    1907        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg, varg);
    1908        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, cand);
    1909        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg, arg);
    1910        9504 :              err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, cand);
    1911             : 
    1912        9504 :                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1913        3168 :                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1914             : 
    1915        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg, arg, nil_matches);
    1916        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg, arg, cand, cand, nil_matches);
    1917        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg, varg, nil_matches);
    1918        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg, varg, cand, nil_matches);
    1919        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg, arg, nil_matches);
    1920        3168 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg, arg, cand, nil_matches);
    1921             :              }
    1922             :           }
    1923             : 
    1924             :           int *tp1, *tp2;
    1925        9504 :           for(tp1 = integer; tp1 < floats && !err; tp1++) {
    1926       47520 :             for(tp2 = integer; tp2 < floats && !err; tp2++) {
    1927       39600 :                 if (*tp1 == *tp2)
    1928        7920 :                         continue;
    1929       31680 :                 mel_func_arg ret = { .type = TYPE_bit, .isbat =1 };
    1930       31680 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1931       31680 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1932       31680 :                 mel_func_arg varg1 = { .type = *tp1 };
    1933       31680 :                 mel_func_arg varg2 = { .type = *tp2 };
    1934             : 
    1935       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 3, ret, arg1, arg2);
    1936       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 5, ret, arg1, arg2, cand, cand);
    1937       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 3, ret, arg1, varg2);
    1938       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg1, varg2, cand);
    1939       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 3, ret, varg1, arg2);
    1940       31680 :                 err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg1, arg2, cand);
    1941             : 
    1942       31680 :                 if (strcmp(cmps[f].op,"==")==0 || strcmp(cmps[f].op,"!=")==0) {
    1943       10560 :                         mel_func_arg nil_matches = { .type = TYPE_bit };
    1944             : 
    1945       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 4, ret, arg1, arg2, nil_matches);
    1946       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment, 1, 6, ret, arg1, arg2, cand, cand, nil_matches);
    1947       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 4, ret, arg1, varg2, nil_matches);
    1948       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v, 1, 5, ret, arg1, varg2, cand, nil_matches);
    1949       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 4, ret, varg1, arg2, nil_matches);
    1950       10560 :                         err += melFunction(false, "batcalc", cmps[f].op, cmps[f].fcn, cmps[f].fname, false, cmps[f].comment_v_, 1, 5, ret, varg1, arg2, cand, nil_matches);
    1951             :                 }
    1952             :             }
    1953             :           }
    1954             :         }
    1955             : 
    1956             :         struct {
    1957             :            char *op;
    1958             :            char *fname;
    1959             :            fptr fcn;
    1960             :            char *comment;
    1961             :            char *comment_v;
    1962             :            char *comment_v_;
    1963             :         } cmp = {
    1964             :                 .op = "cmp",
    1965             :                 .fcn = (fptr)CMDbatCMP,
    1966             :                 .fname = "CMDbatCMP",
    1967             :                 .comment = "Return -1/0/1 if B1 </==/> B2",
    1968             :                 .comment_v = "Return -1/0/1 if B </==/> V",
    1969             :                 .comment_v_ = "Return -1/0/1 if V </==/> B",
    1970             :         };
    1971        1056 :         for(int i = 0; i < 3 && !err; i++) {
    1972         792 :                 int tp = specials[i];
    1973         792 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1974         792 :                 mel_func_arg arg = { .type = tp, .isbat =1 };
    1975         792 :                 mel_func_arg varg = { .type = tp };
    1976             : 
    1977         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg, arg);
    1978         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg, arg, cand, cand);
    1979         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg, varg);
    1980         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg, varg, cand);
    1981         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg, arg);
    1982         792 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg, arg, cand);
    1983             :         }
    1984        2112 :         for(tp1 = integer; tp1 < extra && !err; tp1++) {
    1985       14784 :             for(tp2 = integer; tp2 < extra && !err; tp2++) {
    1986       12936 :                 mel_func_arg ret = { .type = TYPE_bte, .isbat =1 };
    1987       12936 :                 mel_func_arg arg1 = { .type = *tp1, .isbat =1 };
    1988       12936 :                 mel_func_arg arg2 = { .type = *tp2, .isbat =1 };
    1989       12936 :                 mel_func_arg varg1 = { .type = *tp1 };
    1990       12936 :                 mel_func_arg varg2 = { .type = *tp2 };
    1991             : 
    1992       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 3, ret, arg1, arg2);
    1993       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment, 1, 5, ret, arg1, arg2, cand, cand);
    1994       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 3, ret, arg1, varg2);
    1995       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v, 1, 4, ret, arg1, varg2, cand);
    1996       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 3, ret, varg1, arg2);
    1997       12936 :                 err += melFunction(false, "batcalc", cmp.op, cmp.fcn, cmp.fname, false, cmp.comment_v_, 1, 4, ret, varg1, arg2, cand);
    1998             :             }
    1999             :         }
    2000        2112 :         for(tp = integer; tp < extra && !err; tp++) {
    2001        1848 :                 mel_func_arg ret = { .type = TYPE_dbl };
    2002        1848 :                 mel_func_arg nr = { .type = TYPE_lng };
    2003        1848 :                 mel_func_arg arg = { .type = *tp, .isbat =1 };
    2004        1848 :                 mel_func_arg scale = { .type = TYPE_int };
    2005             : 
    2006        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 2, ret, arg);
    2007        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B with candidates list", 1, 3, ret, arg, cand);
    2008        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 3, ret, nr, arg);
    2009        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B with candidates list", 2, 4, ret, nr, arg, cand);
    2010        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B", 1, 3, ret, arg, scale);
    2011        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average of non-nil values of B with candidates list", 1, 4, ret, arg, cand, scale);
    2012        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B", 2, 4, ret, nr, arg, scale);
    2013        1848 :                 err += melFunction(false, "batcalc", "avg", (fptr)&CMDcalcavg, "CMDcalcavg", false, "average and number of non-nil values of B with candidates list", 2, 5, ret, nr, arg, cand, scale);
    2014             :         }
    2015             : 
    2016             :         struct {
    2017             :                 int type;
    2018             :                 char *name;
    2019             :                 char *fname;
    2020             :                 fptr fcn;
    2021             :                 char *name_ne;
    2022             :                 char *fname_ne;
    2023             :                 fptr fcn_ne;
    2024         264 :         } typeops[10] = {
    2025             :           {
    2026             :                 .type = TYPE_bit,
    2027             :                 .name = "bit",
    2028             :                 .name_ne = "bit_noerror",
    2029             :                 .fname = "CMDconvertsignal_bit",
    2030             :                 .fname_ne = "CMDconvert_bit",
    2031             :                 .fcn = (fptr)CMDconvertsignal_bit,
    2032             :                 .fcn_ne = (fptr)CMDconvert_bit,
    2033             :           }, {
    2034             :                 .type = TYPE_bte,
    2035             :                 .name = "bte",
    2036             :                 .name_ne = "bte_noerror",
    2037             :                 .fname = "CMDconvertsignal_bte",
    2038             :                 .fname_ne = "CMDconvert_bte",
    2039             :                 .fcn = (fptr)CMDconvertsignal_bte,
    2040             :                 .fcn_ne = (fptr)CMDconvert_bte,
    2041             :           }, {
    2042             :                 .type = TYPE_sht,
    2043             :                 .name = "sht",
    2044             :                 .name_ne = "sht_noerror",
    2045             :                 .fname = "CMDconvertsignal_sht",
    2046             :                 .fname_ne = "CMDconvert_sht",
    2047             :                 .fcn = (fptr)CMDconvertsignal_sht,
    2048             :                 .fcn_ne = (fptr)CMDconvert_sht,
    2049             :           }, {
    2050             :                 .type = TYPE_int,
    2051             :                 .name = "int",
    2052             :                 .name_ne = "int_noerror",
    2053             :                 .fname = "CMDconvertsignal_int",
    2054             :                 .fname_ne = "CMDconvert_int",
    2055             :                 .fcn = (fptr)CMDconvertsignal_int,
    2056             :                 .fcn_ne = (fptr)CMDconvert_int,
    2057             :           }, {
    2058             :                 .type = TYPE_lng,
    2059             :                 .name = "lng",
    2060             :                 .name_ne = "lng_noerror",
    2061             :                 .fname = "CMDconvertsignal_lng",
    2062             :                 .fname_ne = "CMDconvert_lng",
    2063             :                 .fcn = (fptr)CMDconvertsignal_lng,
    2064             :                 .fcn_ne = (fptr)CMDconvert_lng,
    2065             : #ifdef HAVE_HGE
    2066             :           }, {
    2067             :                 .type = TYPE_hge,
    2068             :                 .name = "hge",
    2069             :                 .name_ne = "hge_noerror",
    2070             :                 .fname = "CMDconvertsignal_hge",
    2071             :                 .fname_ne = "CMDconvert_hge",
    2072             :                 .fcn = (fptr)CMDconvertsignal_hge,
    2073             :                 .fcn_ne = (fptr)CMDconvert_hge,
    2074             : #endif
    2075             :           }, {
    2076             :                 .type = TYPE_flt,
    2077             :                 .name = "flt",
    2078             :                 .name_ne = "flt_noerror",
    2079             :                 .fname = "CMDconvertsignal_flt",
    2080             :                 .fname_ne = "CMDconvert_flt",
    2081             :                 .fcn = (fptr)CMDconvertsignal_flt,
    2082             :                 .fcn_ne = (fptr)CMDconvert_flt,
    2083             :           }, {
    2084             :                 .type = TYPE_dbl,
    2085             :                 .name = "dbl",
    2086             :                 .name_ne = "dbl_noerror",
    2087             :                 .fname = "CMDconvertsignal_dbl",
    2088             :                 .fname_ne = "CMDconvert_dbl",
    2089             :                 .fcn = (fptr)CMDconvertsignal_dbl,
    2090             :                 .fcn_ne = (fptr)CMDconvert_dbl,
    2091             :           }, {
    2092             :                 .type = TYPE_oid,
    2093             :                 .name = "oid",
    2094             :                 .name_ne = "oid_noerror",
    2095             :                 .fname = "CMDconvertsignal_oid",
    2096             :                 .fname_ne = "CMDconvert_oid",
    2097             :                 .fcn = (fptr)CMDconvertsignal_oid,
    2098             :                 .fcn_ne = (fptr)CMDconvert_oid,
    2099             :           }, {
    2100             :                 .type = TYPE_str,
    2101             :                 .name = "str",
    2102             :                 .name_ne = "str_noerror",
    2103             :                 .fname = "CMDconvertsignal_str",
    2104             :                 .fname_ne = "CMDconvert_str",
    2105             :                 .fcn = (fptr)CMDconvertsignal_str,
    2106             :                 .fcn_ne = (fptr)CMDconvert_str,
    2107             :           }
    2108             :         };
    2109             : #ifdef HAVE_HGE
    2110             :         int typeopslen = 10;
    2111             : #else
    2112             :         int typeopslen = 9;
    2113             : #endif
    2114        2904 :         for(int t = 0; t<typeopslen; t++) {
    2115             :                 /* from any 2 string */
    2116        2640 :                 mel_func_arg ret = { .type = typeops[t].type, .isbat =1 };
    2117        2640 :                 if (strcmp(typeops[t].name, "str")==0) {
    2118         264 :                         mel_func_arg arg = { .type = TYPE_any, .isbat =1 };
    2119             : 
    2120         264 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    2121         264 :                         err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    2122         264 :                         err += melFunction(false, "batcalc", typeops[t].name_ne, typeops[t].fcn_ne, typeops[t].fname_ne, false, "", 1, 2, ret, arg);
    2123         264 :                         err += melFunction(false, "batcalc", typeops[t].name_ne, typeops[t].fcn_ne, typeops[t].fname_ne, false, "", 1, 3, ret, arg, cand);
    2124             :                 } else {
    2125       26136 :                     for(int p = 0; p<typeopslen; p++) {
    2126       23760 :                                 mel_func_arg arg = { .type = typeops[p].type, .isbat =1 };
    2127             : 
    2128       23760 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 2, ret, arg);
    2129       23760 :                                 err += melFunction(false, "batcalc", typeops[t].name, typeops[t].fcn, typeops[t].fname, false, "", 1, 3, ret, arg, cand);
    2130       23760 :                                 err += melFunction(false, "batcalc", typeops[t].name_ne, typeops[t].fcn_ne, typeops[t].fname_ne, false, "", 1, 2, ret, arg);
    2131       23760 :                                 err += melFunction(false, "batcalc", typeops[t].name_ne, typeops[t].fcn_ne, typeops[t].fname_ne, false, "", 1, 3, ret, arg, cand);
    2132             :                     }
    2133             :                 }
    2134             :         }
    2135         264 :         return MAL_SUCCEED;
    2136             : }
    2137             : 
    2138             : static mel_func batcalc_init_funcs[] = {
    2139             :  /* batcalc */
    2140             :  pattern("batcalc", "isnil", CMDbatISNIL, false, "Unary check for nil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    2141             :  pattern("batcalc", "isnil", CMDbatISNIL, false, "Unary check for nil over the tail of the bat with candidates list", args(1,3, batarg("",bit),batargany("b",0),batarg("s",oid))),
    2142             :  pattern("batcalc", "isnotnil", CMDbatISNOTNIL, false, "Unary check for notnil over the tail of the bat", args(1,2, batarg("",bit),batargany("b",0))),
    2143             :  pattern("batcalc", "isnotnil", CMDbatISNOTNIL, false, "Unary check for notnil over the tail of the bat with candidates list", args(1,3, batarg("",bit),batargany("b",0),batarg("s",oid))),
    2144             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    2145             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    2146             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    2147             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    2148             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    2149             :  pattern("batcalc", "min", CMDbatMIN, false, "Return bat with minimum value of each pair of inputs", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    2150             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    2151             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    2152             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    2153             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    2154             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    2155             :  pattern("batcalc", "min_no_nil", CMDbatMIN_no_nil, false, "Return bat with minimum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    2156             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    2157             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    2158             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    2159             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    2160             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    2161             :  pattern("batcalc", "max", CMDbatMAX, false, "Return bat with maximum value of each pair of inputs", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    2162             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b1",1),batargany("b2",1))),
    2163             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,5, batargany("",1),batargany("b1",1),batargany("b2",1),batarg("s1",oid),batarg("s2",oid))),
    2164             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),batargany("b",1),argany("v",1))),
    2165             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),batargany("b",1),argany("v",1),batarg("s",oid))),
    2166             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,3, batargany("",1),argany("v",1),batargany("b",1))),
    2167             :  pattern("batcalc", "max_no_nil", CMDbatMAX_no_nil, false, "Return bat with maximum value of each pair of inputs, ignoring nil values", args(1,4, batargany("",1),argany("v",1),batargany("b",1),batarg("s",oid))),
    2168             : 
    2169             :  pattern("batcalc", "+", CMDbatADD, false, "Return concatenation of B1 and B2 with candidates list", args(1,5, batarg("",str),batarg("b1",str),batarg("b2",str),batarg("s1",oid),batarg("s2",oid))),
    2170             :  pattern("batcalc", "+", CMDbatADD, false, "Return concatenation of B and V with candidates list", args(1,4, batarg("",str),batarg("b",str),arg("v",str),batarg("s",oid))),
    2171             :  pattern("batcalc", "+", CMDbatADD, false, "Return concatenation of V and B with candidates list", args(1,4, batarg("",str),arg("v",str),batarg("b",str),batarg("s",oid))),
    2172             : 
    2173             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",dbl),batarg("x",dbl),arg("y",dbl))),
    2174             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",dbl),batarg("x",dbl),arg("y",dbl),batarg("s",oid))),
    2175             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,3, batarg("",flt),batarg("x",flt),arg("y",flt))),
    2176             :  pattern("batmmath", "fmod", CMDbatMODsignal, false, "", args(1,4, batarg("",flt),batarg("x",flt),arg("y",flt),batarg("s",oid))),
    2177             : 
    2178             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),batargany("v1",1),batargany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2179             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,12, batarg("",bit),batargany("b",1),batargany("v1",1),batargany("v2",1),batarg("s",oid),batarg("s1",oid),batarg("s2",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2180             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),batargany("v1",1),argany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2181             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,11, batarg("",bit),batargany("b",1),batargany("v1",1),argany("v2",1),batarg("s",oid),batarg("s1",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2182             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),argany("v1",1),batargany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2183             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,11, batarg("",bit),batargany("b",1),argany("v1",1),batargany("v2",1),batarg("s",oid),batarg("s2",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2184             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa)", args(1,9, batarg("",bit),batargany("b",1),argany("v1",1),argany("v2",1),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2185             :  pattern("batcalc", "between", CMDbatBETWEEN, false, "B between V1 and V2 (or vice versa) with candidates list", args(1,10, batarg("",bit),batargany("b",1),argany("v1",1),argany("v2",1),batarg("s",oid),arg("sym",bit),arg("linc",bit),arg("hinc",bit),arg("nils_false",bit),arg("anti",bit))),
    2186             : 
    2187             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
    2188             :  pattern("aggr", "avg", CMDcalcavg, false, "Gives the avg of all tail values", args(1,3, arg("",dbl),batargany("b",2),arg("scale",int))),
    2189             : 
    2190             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),batargany("b1",1),batargany("b2",1))),
    2191             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),argany("v1",1),batargany("b2",1))),
    2192             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),arg("v",bit),batargany("b1",1),argany("v2",1))),
    2193             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),argany("v1",1),argany("v2",1))),
    2194             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),batargany("b1",1),argany("v2",1))),
    2195             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),argany("v1",1),batargany("b2",1))),
    2196             :  pattern("batcalc", "ifthenelse", CMDifthen, false, "If-then-else operation to assemble a conditional result", args(1,4, batargany("",1),batarg("b",bit),batargany("b1",1),batargany("b2",1))),
    2197             :  { .imp=NULL }
    2198             : };
    2199             : #include "mal_import.h"
    2200             : #ifdef _MSC_VER
    2201             : #undef read
    2202             : #pragma section(".CRT$XCU",read)
    2203             : #endif
    2204         257 : LIB_STARTUP_FUNC(init_batcalc_mal)
    2205         257 : { mal_module2("batcalc", NULL, batcalc_init_funcs, &batcalc_init, NULL); }

Generated by: LCOV version 1.14