LCOV - code coverage report
Current view: top level - monetdb5/modules/atoms - uuid.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 96 273 35.2 %
Date: 2024-04-26 00:35:57 Functions: 9 14 64.3 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /*
      14             :  * K.S. Mullender & A. de Rijke
      15             :  * The UUID module
      16             :  * The UUID module contains a wrapper for all function in
      17             :  * libuuid.
      18             :  */
      19             : 
      20             : #include "monetdb_config.h"
      21             : #if defined(HAVE_GETENTROPY) && defined(HAVE_SYS_RANDOM_H)
      22             : #include <sys/random.h>
      23             : #endif
      24             : #include "mal.h"
      25             : #include "mal_exception.h"
      26             : #include "mal_interpreter.h"
      27             : 
      28             : #if !defined(HAVE_GETENTROPY) && defined(HAVE_RAND_S)
      29             : static inline bool
      30             : generate_uuid(uuid *U)
      31             : {
      32             :         union {
      33             :                 unsigned int randbuf[4];
      34             :                 unsigned char uuid[16];
      35             :         } u;
      36             :         for (int i = 0; i < 4; i++)
      37             :                 if (rand_s(&u.randbuf[i]) != 0)
      38             :                         return false;
      39             :         /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
      40             :         u.uuid[8] = (u.uuid[8] & 0x3F) |0x80;
      41             :         /* make sure this is version 4 (random UUID) */
      42             :         u.uuid[6] = (u.uuid[6] & 0x0F) |0x40;
      43             :         memcpy(U->u, u.uuid, 16);
      44             :         return true;
      45             : }
      46             : #endif
      47             : 
      48             : /**
      49             :  * Returns the string representation of the given uuid value.
      50             :  * Warning: GDK function
      51             :  * Returns the length of the string
      52             :  */
      53             : static inline void
      54         102 : UUIDgenerateUuid_internal(uuid *u)
      55             : {
      56             : #if defined(HAVE_GETENTROPY)
      57         102 :         if (getentropy(u->u, 16) == 0) {
      58             :                 /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
      59         102 :                 u->u[8] = (u->u[8] & 0x3F) | 0x80;
      60             :                 /* make sure this is version 4 (random UUID) */
      61         102 :                 u->u[6] = (u->u[6] & 0x0F) | 0x40;
      62             :         } else
      63             : #elif defined(HAVE_RAND_S)
      64             :         if (!generate_uuid(u))
      65             : #endif
      66             :         {
      67             :                 /* generate something like this:
      68             :                  * cefa7a9c-1dd2-41b2-8350-880020adbeef
      69             :                  * ("%08x-%04x-%04x-%04x-%012x") */
      70           0 :                 for (int i = 0; i < 16; i += 2) {
      71             : #ifdef __COVERITY__
      72             :                         int r = 0;
      73             : #else
      74           0 :                         int r = rand();
      75             : #endif
      76           0 :                         u->u[i] = (unsigned char) (r >> 8);
      77           0 :                         u->u[i + 1] = (unsigned char) r;
      78             :                 }
      79             :                 /* make sure this is a variant 1 UUID (RFC 4122/DCE 1.1) */
      80           0 :                 u->u[8] = (u->u[8] & 0x3F) | 0x80;
      81             :                 /* make sure this is version 4 (random UUID) */
      82           0 :                 u->u[6] = (u->u[6] & 0x0F) | 0x40;
      83             :         }
      84         102 : }
      85             : 
      86             : static str
      87         102 : UUIDgenerateUuid(uuid *retval)
      88             : {
      89         102 :         UUIDgenerateUuid_internal(retval);
      90         102 :         return MAL_SUCCEED;
      91             : }
      92             : 
      93             : static str
      94           0 : UUIDgenerateUuidInt(uuid *retval, int *d)
      95             : {
      96           0 :         (void) d;
      97           0 :         return UUIDgenerateUuid(retval);
      98             : }
      99             : 
     100             : static inline bit
     101          99 : isaUUID(const char *s)
     102             : {
     103          99 :         uuid u, *pu = &u;
     104          99 :         size_t l = UUID_SIZE;
     105          99 :         ssize_t res = BATatoms[TYPE_uuid].atomFromStr(s, &l, (void **) &pu, false);
     106             : 
     107          99 :         if (res > 1)
     108             :                 return true;
     109          83 :         else if (res == 1)
     110          31 :                 return bit_nil;
     111             :         else
     112             :                 return false;
     113             : }
     114             : 
     115             : static str
     116           0 : UUIDgenerateUuidInt_bulk(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
     117             :                                                  InstrPtr pci)
     118             : {
     119           0 :         BAT *b = NULL, *bn = NULL;
     120           0 :         BUN n = 0;
     121           0 :         str msg = MAL_SUCCEED;
     122           0 :         uuid *restrict bnt = NULL;
     123           0 :         bat *ret = getArgReference_bat(stk, pci, 0);
     124             : 
     125           0 :         (void) cntxt;
     126           0 :         if (isaBatType(getArgType(mb, pci, 1))) {
     127           0 :                 bat *bid = getArgReference_bat(stk, pci, 1);
     128           0 :                 if (!(b = BBPquickdesc(*bid))) {
     129           0 :                         throw(MAL, "uuid.generateuuidint_bulk",
     130             :                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     131             :                 }
     132           0 :                 n = BATcount(b);
     133             :         } else {
     134           0 :                 n = (BUN) *getArgReference_lng(stk, pci, 1);
     135             :         }
     136             : 
     137           0 :         if ((bn = COLnew(b ? b->hseqbase : 0, TYPE_uuid, n, TRANSIENT)) == NULL) {
     138           0 :                 throw(MAL, "uuid.generateuuidint_bulk",
     139             :                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     140             :         }
     141           0 :         bnt = Tloc(bn, 0);
     142           0 :         for (BUN i = 0; i < n; i++)
     143           0 :                 UUIDgenerateUuid_internal(&(bnt[i]));
     144           0 :         BATsetcount(bn, n);
     145           0 :         bn->tnonil = true;
     146           0 :         bn->tnil = false;
     147           0 :         bn->tsorted = n <= 1;
     148           0 :         bn->trevsorted = n <= 1;
     149           0 :         bn->tkey = n <= 1;
     150           0 :         *ret = bn->batCacheid;
     151           0 :         BBPkeepref(bn);
     152           0 :         return msg;
     153             : }
     154             : 
     155             : static str
     156          31 : UUIDisaUUID(bit *retval, str *s)
     157             : {
     158          31 :         *retval = isaUUID(*s);
     159          31 :         if (*retval == false)
     160          26 :                 GDKclrerr();
     161          31 :         return MAL_SUCCEED;
     162             : }
     163             : 
     164             : static str
     165          21 : UUIDisaUUID_bulk(bat *ret, const bat *bid)
     166             : {
     167          21 :         BAT *b = NULL, *bn = NULL;
     168          21 :         BUN q;
     169          21 :         bit *restrict dst;
     170          21 :         str msg = MAL_SUCCEED;
     171          21 :         BATiter bi;
     172             : 
     173          21 :         if ((b = BATdescriptor(*bid)) == NULL) {
     174           0 :                 msg = createException(MAL, "uuid.isaUUID_bulk",
     175             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     176           0 :                 goto bailout;
     177             :         }
     178          21 :         q = BATcount(b);
     179          21 :         if ((bn = COLnew(b->hseqbase, TYPE_bit, q, TRANSIENT)) == NULL) {
     180           0 :                 msg = createException(MAL, "uuid.isaUUID_bulk",
     181             :                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     182           0 :                 goto bailout;
     183             :         }
     184          21 :         dst = Tloc(bn, 0);
     185          21 :         bi = bat_iterator(b);
     186          89 :         for (BUN p = 0; p < q; p++)
     187          68 :                 dst[p] = isaUUID(BUNtvar(bi, p));
     188          21 :         GDKclrerr();                            /* Not interested in atomFromStr errors */
     189          21 :         BATsetcount(bn, q);
     190          21 :         bn->tnonil = bi.nonil;
     191          21 :         bn->tnil = bi.nil;
     192          21 :         bn->tsorted = bn->trevsorted = q < 2;
     193          21 :         bn->tkey = false;
     194          21 :         bat_iterator_end(&bi);
     195          21 :   bailout:
     196          21 :         BBPreclaim(b);
     197          21 :         if (bn) {                                       /* implies msg==MAL_SUCCEED */
     198          21 :                 *ret = bn->batCacheid;
     199          21 :                 BBPkeepref(bn);
     200             :         }
     201          21 :         return msg;
     202             : }
     203             : 
     204             : static str
     205           0 : UUIDuuid2uuid(uuid *retval, uuid *i)
     206             : {
     207           0 :         *retval = *i;
     208           0 :         return MAL_SUCCEED;
     209             : }
     210             : 
     211             : static str
     212           0 : UUIDuuid2uuid_bulk(bat *res, const bat *bid, const bat *sid)
     213             : {
     214           0 :         BAT *b = NULL, *s = NULL, *dst = NULL;
     215           0 :         uuid *restrict bv, *restrict dv;
     216           0 :         str msg = NULL;
     217           0 :         struct canditer ci;
     218           0 :         oid off;
     219           0 :         bool nils = false, btsorted = false, btrevsorted = false, btkey = false;
     220           0 :         BATiter bi;
     221             : 
     222           0 :         if (sid && !is_bat_nil(*sid)) {
     223           0 :                 if ((s = BATdescriptor(*sid)) == NULL) {
     224           0 :                         msg = createException(SQL, "batcalc.uuid2uuidbulk",
     225             :                                                                   SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     226           0 :                         goto bailout;
     227             :                 }
     228             :         } else {
     229           0 :                 BBPretain(*res = *bid); /* nothing to convert, return */
     230           0 :                 return MAL_SUCCEED;
     231             :         }
     232           0 :         if ((b = BATdescriptor(*bid)) == NULL) {
     233           0 :                 msg = createException(SQL, "batcalc.uuid2uuidbulk",
     234             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     235           0 :                 goto bailout;
     236             :         }
     237           0 :         off = b->hseqbase;
     238           0 :         canditer_init(&ci, b, s);
     239           0 :         if (!(dst = COLnew(ci.hseq, TYPE_uuid, ci.ncand, TRANSIENT))) {
     240           0 :                 msg = createException(SQL, "batcalc.uuid2uuidbulk",
     241             :                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     242           0 :                 goto bailout;
     243             :         }
     244             : 
     245           0 :         bi = bat_iterator(b);
     246           0 :         bv = bi.base;
     247           0 :         dv = Tloc(dst, 0);
     248           0 :         if (ci.tpe == cand_dense) {
     249           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     250           0 :                         oid p = (canditer_next_dense(&ci) - off);
     251           0 :                         uuid v = bv[p];
     252             : 
     253           0 :                         dv[i] = v;
     254           0 :                         nils |= is_uuid_nil(v);
     255             :                 }
     256             :         } else {
     257           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     258           0 :                         oid p = (canditer_next(&ci) - off);
     259           0 :                         uuid v = bv[p];
     260             : 
     261           0 :                         dv[i] = v;
     262           0 :                         nils |= is_uuid_nil(v);
     263             :                 }
     264             :         }
     265           0 :         btkey = bi.key;
     266           0 :         btsorted = bi.sorted;
     267           0 :         btrevsorted = bi.revsorted;
     268           0 :         bat_iterator_end(&bi);
     269             : 
     270           0 :   bailout:
     271           0 :         BBPreclaim(b);
     272           0 :         BBPreclaim(s);
     273           0 :         if (dst) {                                      /* implies msg==MAL_SUCCEED */
     274           0 :                 BATsetcount(dst, ci.ncand);
     275           0 :                 dst->tnil = nils;
     276           0 :                 dst->tnonil = !nils;
     277           0 :                 dst->tkey = btkey;
     278           0 :                 dst->tsorted = btsorted;
     279           0 :                 dst->trevsorted = btrevsorted;
     280           0 :                 *res = dst->batCacheid;
     281           0 :                 BBPkeepref(dst);
     282             :         }
     283             :         return msg;
     284             : }
     285             : 
     286             : static str
     287          59 : UUIDstr2uuid(uuid *retval, str *s)
     288             : {
     289          59 :         size_t l = UUID_SIZE;
     290             : 
     291          59 :         if (BATatoms[TYPE_uuid].atomFromStr(*s, &l, (void **) &retval, false) > 0) {
     292             :                 return MAL_SUCCEED;
     293             :         }
     294           6 :         throw(MAL, "uuid.uuid", "Not a UUID");
     295             : }
     296             : 
     297             : static str
     298           2 : UUIDstr2uuid_bulk(bat *res, const bat *bid, const bat *sid)
     299             : {
     300           2 :         BAT *b = NULL, *s = NULL, *dst = NULL;
     301           2 :         BATiter bi;
     302           2 :         str msg = NULL;
     303           2 :         uuid *restrict vals;
     304           2 :         struct canditer ci;
     305           2 :         oid off;
     306           2 :         bool nils = false, btkey = false;
     307           2 :         size_t l = UUID_SIZE;
     308           2 :         ssize_t (*conv)(const char *, size_t *, void **, bool) = BATatoms[TYPE_uuid].atomFromStr;
     309             : 
     310           2 :         if ((b = BATdescriptor(*bid)) == NULL) {
     311           0 :                 msg = createException(SQL, "batcalc.str2uuidbulk",
     312             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     313           0 :                 goto bailout;
     314             :         }
     315           2 :         if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
     316           0 :                 msg = createException(SQL, "batcalc.str2uuidbulk",
     317             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     318           0 :                 goto bailout;
     319             :         }
     320           2 :         off = b->hseqbase;
     321           2 :         canditer_init(&ci, b, s);
     322           2 :         if (!(dst = COLnew(ci.hseq, TYPE_uuid, ci.ncand, TRANSIENT))) {
     323           0 :                 msg = createException(SQL, "batcalc.str2uuidbulk",
     324             :                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     325           0 :                 goto bailout;
     326             :         }
     327             : 
     328           2 :         bi = bat_iterator(b);
     329           2 :         vals = Tloc(dst, 0);
     330           2 :         if (ci.tpe == cand_dense) {
     331           4 :                 for (BUN i = 0; i < ci.ncand; i++) {
     332           2 :                         oid p = (canditer_next_dense(&ci) - off);
     333           2 :                         const char *v = BUNtvar(bi, p);
     334           2 :                         uuid *up = &vals[i], **pp = &up;
     335             : 
     336           2 :                         if (conv(v, &l, (void **) pp, false) <= 0) {
     337           0 :                                 msg = createException(SQL, "batcalc.str2uuidbulk",
     338             :                                                                           SQLSTATE(42000) "Not a UUID");
     339           0 :                                 goto bailout1;
     340             :                         }
     341           4 :                         nils |= strNil(v);
     342             :                 }
     343             :         } else {
     344           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     345           0 :                         oid p = (canditer_next(&ci) - off);
     346           0 :                         const char *v = BUNtvar(bi, p);
     347           0 :                         uuid *up = &vals[i], **pp = &up;
     348             : 
     349           0 :                         if (conv(v, &l, (void **) pp, false) <= 0) {
     350           0 :                                 msg = createException(SQL, "batcalc.str2uuidbulk",
     351             :                                                                           SQLSTATE(42000) "Not a UUID");
     352           0 :                                 goto bailout1;
     353             :                         }
     354           0 :                         nils |= strNil(v);
     355             :                 }
     356             :         }
     357           2 :         btkey = bi.key;
     358           2 :   bailout1:
     359           2 :         bat_iterator_end(&bi);
     360             : 
     361           2 :   bailout:
     362           2 :         BBPreclaim(b);
     363           2 :         BBPreclaim(s);
     364           2 :         if (dst && !msg) {
     365           2 :                 BATsetcount(dst, ci.ncand);
     366           2 :                 dst->tnil = nils;
     367           2 :                 dst->tnonil = !nils;
     368           2 :                 dst->tkey = btkey;
     369           2 :                 dst->tsorted = BATcount(dst) <= 1;
     370           2 :                 dst->trevsorted = BATcount(dst) <= 1;
     371           2 :                 *res = dst->batCacheid;
     372           2 :                 BBPkeepref(dst);
     373           0 :         } else if (dst)
     374           0 :                 BBPreclaim(dst);
     375           2 :         return msg;
     376             : }
     377             : 
     378             : static str
     379         101 : UUIDuuid2str(str *retval, const uuid *u)
     380             : {
     381         101 :         size_t l = 0;
     382         101 :         *retval = NULL;
     383         101 :         if (BATatoms[TYPE_uuid].atomToStr(retval, &l, u, false) < 0)
     384           0 :                 throw(MAL, "uuid.str", GDK_EXCEPTION);
     385             :         return MAL_SUCCEED;
     386             : }
     387             : 
     388             : static str
     389           0 : UUIDuuid2str_bulk(bat *res, const bat *bid, const bat *sid)
     390             : {
     391           0 :         BAT *b = NULL, *s = NULL, *dst = NULL;
     392           0 :         str msg = NULL;
     393           0 :         uuid *restrict vals;
     394           0 :         struct canditer ci;
     395           0 :         oid off;
     396           0 :         bool nils = false, btkey = false;
     397           0 :         char buf[UUID_STRLEN + 2], *pbuf = buf;
     398           0 :         size_t l = sizeof(buf);
     399           0 :         ssize_t (*conv)(char **, size_t *, const void *, bool) = BATatoms[TYPE_uuid].atomToStr;
     400           0 :         BATiter bi;
     401             : 
     402           0 :         if ((b = BATdescriptor(*bid)) == NULL) {
     403           0 :                 msg = createException(SQL, "batcalc.uuid2strbulk",
     404             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     405           0 :                 goto bailout;
     406             :         }
     407           0 :         if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
     408           0 :                 msg = createException(SQL, "batcalc.uuid2strbulk",
     409             :                                                           SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     410           0 :                 goto bailout;
     411             :         }
     412           0 :         off = b->hseqbase;
     413           0 :         canditer_init(&ci, b, s);
     414           0 :         if (!(dst = COLnew(ci.hseq, TYPE_str, ci.ncand, TRANSIENT))) {
     415           0 :                 msg = createException(SQL, "batcalc.uuid2strbulk",
     416             :                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     417           0 :                 goto bailout;
     418             :         }
     419             : 
     420           0 :         bi = bat_iterator(b);
     421           0 :         vals = bi.base;
     422           0 :         if (ci.tpe == cand_dense) {
     423           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     424           0 :                         oid p = (canditer_next_dense(&ci) - off);
     425           0 :                         uuid v = vals[p];
     426             : 
     427           0 :                         if (conv(&pbuf, &l, &v, false) < 0) {    /* it should never be reallocated */
     428           0 :                                 msg = createException(MAL, "batcalc.uuid2strbulk",
     429             :                                                                           GDK_EXCEPTION);
     430           0 :                                 goto bailout1;
     431             :                         }
     432           0 :                         if (tfastins_nocheckVAR(dst, i, buf) != GDK_SUCCEED) {
     433           0 :                                 msg = createException(SQL, "batcalc.uuid2strbulk",
     434             :                                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     435           0 :                                 goto bailout1;
     436             :                         }
     437           0 :                         nils |= strNil(buf);
     438             :                 }
     439             :         } else {
     440           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     441           0 :                         oid p = (canditer_next(&ci) - off);
     442           0 :                         uuid v = vals[p];
     443             : 
     444           0 :                         if (conv(&pbuf, &l, &v, false) < 0) {    /* it should never be reallocated */
     445           0 :                                 msg = createException(MAL, "batcalc.uuid2strbulk",
     446             :                                                                           GDK_EXCEPTION);
     447           0 :                                 goto bailout1;
     448             :                         }
     449           0 :                         if (tfastins_nocheckVAR(dst, i, buf) != GDK_SUCCEED) {
     450           0 :                                 msg = createException(SQL, "batcalc.uuid2strbulk",
     451             :                                                                           SQLSTATE(HY013) MAL_MALLOC_FAIL);
     452           0 :                                 goto bailout1;
     453             :                         }
     454           0 :                         nils |= strNil(buf);
     455             :                 }
     456             :         }
     457           0 :         btkey = bi.key;
     458           0 :   bailout1:
     459           0 :         bat_iterator_end(&bi);
     460             : 
     461           0 :   bailout:
     462           0 :         BBPreclaim(b);
     463           0 :         BBPreclaim(s);
     464           0 :         if (dst && !msg) {
     465           0 :                 BATsetcount(dst, ci.ncand);
     466           0 :                 dst->tnil = nils;
     467           0 :                 dst->tnonil = !nils;
     468           0 :                 dst->tkey = btkey;
     469           0 :                 dst->tsorted = BATcount(dst) <= 1;
     470           0 :                 dst->trevsorted = BATcount(dst) <= 1;
     471           0 :                 *res = dst->batCacheid;
     472           0 :                 BBPkeepref(dst);
     473           0 :         } else if (dst)
     474           0 :                 BBPreclaim(dst);
     475           0 :         return msg;
     476             : }
     477             : 
     478             : #include "mel.h"
     479             : mel_func uuid_init_funcs[] = {
     480             :  command("uuid", "new", UUIDgenerateUuid, true, "Generate a new uuid", args(1,1, arg("",uuid))),
     481             :  command("uuid", "new", UUIDgenerateUuidInt, false, "Generate a new uuid (dummy version for side effect free multiplex loop)", args(1,2, arg("",uuid),arg("d",int))),
     482             :  pattern("batuuid", "new", UUIDgenerateUuidInt_bulk, false, "Generate a new uuid (dummy version for side effect free multiplex loop)", args(1,2, batarg("",uuid),batarg("d",int))),
     483             :  pattern("batuuid", "new", UUIDgenerateUuidInt_bulk, false, "Generate a new uuid (dummy version for side effect free multiplex loop)", args(1,2, batarg("",uuid),arg("card",lng))), /* version with cardinality input */
     484             :  command("uuid", "uuid", UUIDstr2uuid, false, "Coerce a string to a uuid, validating its format", args(1,2, arg("",uuid),arg("s",str))),
     485             :  command("uuid", "str", UUIDuuid2str, false, "Coerce a uuid to its string type", args(1,2, arg("",str),arg("u",uuid))),
     486             :  command("uuid", "isaUUID", UUIDisaUUID, false, "Test a string for a UUID format", args(1,2, arg("",bit),arg("u",str))),
     487             :  command("batuuid", "isaUUID", UUIDisaUUID_bulk, false, "Test a string for a UUID format", args(1,2, batarg("",bit),batarg("u",str))),
     488             :  command("calc", "uuid", UUIDstr2uuid, false, "Coerce a string to a uuid, validating its format", args(1,2, arg("",uuid),arg("s",str))),
     489             :  command("batcalc", "uuid", UUIDstr2uuid_bulk, false, "Coerce a string to a uuid, validating its format", args(1,3, batarg("",uuid),batarg("s",str),batarg("c",oid))),
     490             :  command("calc", "uuid", UUIDuuid2uuid, false, "", args(1,2, arg("",uuid),arg("u",uuid))),
     491             :  command("batcalc", "uuid", UUIDuuid2uuid_bulk, false, "", args(1,3, batarg("",uuid),batarg("u",uuid),batarg("c",oid))),
     492             :  command("calc", "str", UUIDuuid2str, false, "Coerce a uuid to a string type", args(1,2, arg("",str),arg("s",uuid))),
     493             :  command("batcalc", "str", UUIDuuid2str_bulk, false, "Coerce a uuid to a string type", args(1,3, batarg("",str),batarg("s",uuid),batarg("c",oid))),
     494             :  { .imp=NULL }
     495             : };
     496             : #include "mal_import.h"
     497             : #ifdef _MSC_VER
     498             : #undef read
     499             : #pragma section(".CRT$XCU",read)
     500             : #endif
     501         334 : LIB_STARTUP_FUNC(init_uuid_mal)
     502         334 : { mal_module("uuid", NULL, uuid_init_funcs); }

Generated by: LCOV version 1.14