LCOV - code coverage report
Current view: top level - monetdb5/mal - mal_atom.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 36 120 30.0 %
Date: 2024-04-25 20:03:45 Functions: 4 5 80.0 %

          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             :  * (author) M.L.Kersten
      15             :  * Every MAL command introduced in an atom module should be checked
      16             :  * to detect overloading of a predefined function.
      17             :  * Subsequently, we update the GDK atom structure.
      18             :  * The function signatures should be parameter-less, which
      19             :  * enables additional functions with the same name to appear
      20             :  * as ordinary mal operators.
      21             :  *
      22             :  * A few fields are set only once, at creation time.
      23             :  * They should be implemented with parameter-less functions.
      24             :  */
      25             : #include "monetdb_config.h"
      26             : #include "mal_instruction.h"
      27             : #include "mal_atom.h"
      28             : #include "mal_namespace.h"
      29             : #include "mal_exception.h"
      30             : #include "mal_private.h"
      31             : 
      32             : static void
      33           0 : setAtomName(InstrPtr pci)
      34             : {
      35           0 :         char buf[FILENAME_MAX];
      36           0 :         snprintf(buf, FILENAME_MAX, "#%s", getFunctionId(pci));
      37           0 :         setFunctionId(pci, putName(buf));
      38           0 : }
      39             : 
      40             : str
      41           3 : malAtomProperty(MalBlkPtr mb, InstrPtr pci)
      42             : {
      43           3 :         const char *name;
      44           3 :         int tpe;
      45           3 :         (void) mb;                                      /* fool compilers */
      46           3 :         assert(pci != 0);
      47           3 :         name = getFunctionId(pci);
      48           3 :         tpe = getAtomIndex(getModuleId(pci), strlen(getModuleId(pci)), TYPE_any);
      49           3 :         if (tpe < 0 || tpe >= GDKatomcnt || tpe >= MAXATOMS)
      50             :                 return MAL_SUCCEED;
      51           3 :         assert(pci->fcn != NULL);
      52           3 :         switch (name[0]) {
      53           0 :         case 'd':
      54           0 :                 if (idcmp("del", name) == 0 && pci->argc == 1) {
      55           0 :                         BATatoms[tpe].atomDel = (void (*)(Heap *, var_t *)) pci->fcn;
      56           0 :                         setAtomName(pci);
      57           0 :                         return MAL_SUCCEED;
      58             :                 }
      59             :                 break;
      60           0 :         case 'c':
      61           0 :                 if (idcmp("cmp", name) == 0 && pci->argc == 1) {
      62           0 :                         BATatoms[tpe].atomCmp = (int (*)(const void *, const void *)) pci->fcn;
      63           0 :                         BATatoms[tpe].linear = true;
      64           0 :                         setAtomName(pci);
      65           0 :                         return MAL_SUCCEED;
      66             :                 }
      67             :                 break;
      68           3 :         case 'f':
      69           3 :                 if (idcmp("fromstr", name) == 0 && pci->argc == 1) {
      70           0 :                         BATatoms[tpe].atomFromStr = (ssize_t (*)(const char *, size_t *, ptr *, bool)) pci->fcn;
      71           0 :                         setAtomName(pci);
      72           0 :                         return MAL_SUCCEED;
      73             :                 }
      74           3 :                 if (idcmp("fix", name) == 0 && pci->argc == 1) {
      75           0 :                         BATatoms[tpe].atomFix = (gdk_return (*)(const void *)) pci->fcn;
      76           0 :                         setAtomName(pci);
      77           0 :                         return MAL_SUCCEED;
      78             :                 }
      79             :                 break;
      80           0 :         case 'h':
      81           0 :                 if (idcmp("heap", name) == 0 && pci->argc == 1) {
      82             :                         /* heap function makes an atom varsized */
      83           0 :                         BATatoms[tpe].size = sizeof(var_t);
      84           0 :                         assert_shift_width(ATOMelmshift(ATOMsize(tpe)), ATOMsize(tpe));
      85           0 :                         BATatoms[tpe].atomHeap = (gdk_return (*)(Heap *, size_t)) pci->fcn;
      86           0 :                         setAtomName(pci);
      87           0 :                         return MAL_SUCCEED;
      88             :                 }
      89           0 :                 if (idcmp("hash", name) == 0 && pci->argc == 1) {
      90           0 :                         BATatoms[tpe].atomHash = (BUN (*)(const void *)) pci->fcn;
      91           0 :                         setAtomName(pci);
      92           0 :                         return MAL_SUCCEED;
      93             :                 }
      94             :                 break;
      95           0 :         case 'l':
      96           0 :                 if (idcmp("length", name) == 0 && pci->argc == 1) {
      97           0 :                         BATatoms[tpe].atomLen = (size_t (*)(const void *)) pci->fcn;
      98           0 :                         setAtomName(pci);
      99           0 :                         return MAL_SUCCEED;
     100             :                 }
     101             :                 break;
     102           0 :         case 'n':
     103           0 :                 if (idcmp("null", name) == 0 && pci->argc == 1) {
     104           0 :                         const void *atmnull = ((const void *(*)(void)) pci->fcn)();
     105             : 
     106           0 :                         BATatoms[tpe].atomNull = atmnull;
     107           0 :                         setAtomName(pci);
     108           0 :                         return MAL_SUCCEED;
     109             :                 }
     110           0 :                 if (idcmp("nequal", name) == 0 && pci->argc == 1) {
     111           0 :                         BATatoms[tpe].atomCmp = (int (*)(const void *, const void *)) pci->fcn;
     112           0 :                         setAtomName(pci);
     113           0 :                         return MAL_SUCCEED;
     114             :                 }
     115             :                 break;
     116           0 :         case 'p':
     117           0 :                 if (idcmp("put", name) == 0 && pci->argc == 1) {
     118           0 :                         BATatoms[tpe].atomPut = (var_t (*)(BAT *, var_t *, const void *)) pci->fcn;
     119           0 :                         setAtomName(pci);
     120           0 :                         return MAL_SUCCEED;
     121             :                 }
     122             :                 break;
     123           0 :         case 's':
     124           0 :                 if (idcmp("storage", name) == 0 && pci->argc == 1) {
     125           0 :                         BATatoms[tpe].storage = (*(int (*)(void)) pci->fcn) ();
     126           0 :                         setAtomName(pci);
     127           0 :                         return MAL_SUCCEED;
     128             :                 }
     129             :                 break;
     130           0 :         case 't':
     131           0 :                 if (idcmp("tostr", name) == 0 && pci->argc == 1) {
     132           0 :                         BATatoms[tpe].atomToStr = (ssize_t (*)(str *, size_t *, const void *, bool)) pci->fcn;
     133           0 :                         setAtomName(pci);
     134           0 :                         return MAL_SUCCEED;
     135             :                 }
     136             :                 break;
     137           0 :         case 'u':
     138           0 :                 if (idcmp("unfix", name) == 0 && pci->argc == 1) {
     139           0 :                         BATatoms[tpe].atomUnfix = (gdk_return (*)(const void *)) pci->fcn;
     140           0 :                         setAtomName(pci);
     141           0 :                         return MAL_SUCCEED;
     142             :                 }
     143             :                 break;
     144           0 :         case 'r':
     145           0 :                 if (idcmp("read", name) == 0 && pci->argc == 1) {
     146           0 :                         BATatoms[tpe].atomRead = (void *(*)(void *, size_t *, stream *, size_t)) pci->fcn;
     147           0 :                         setAtomName(pci);
     148           0 :                         return MAL_SUCCEED;
     149             :                 }
     150             :                 break;
     151           0 :         case 'w':
     152           0 :                 if (idcmp("write", name) == 0 && pci->argc == 1) {
     153           0 :                         BATatoms[tpe].atomWrite = (gdk_return (*)(const void *, stream *, size_t)) pci->fcn;
     154           0 :                         setAtomName(pci);
     155           0 :                         return MAL_SUCCEED;
     156             :                 }
     157             :                 break;
     158             :         }
     159             :         return MAL_SUCCEED;
     160             : }
     161             : 
     162             : /*
     163             :  * Atoms are constructed incrementally in the kernel using the
     164             :  * ATOMallocate function. It takes an existing type as a base
     165             :  * to derive a new one.
     166             :  * The most tedisous work is to check the signature types of the functions
     167             :  * acceptable for the kernel.
     168             :  */
     169             : 
     170             : str
     171           4 : malAtomDefinition(const char *name, int tpe)
     172             : {
     173           4 :         int i;
     174             : 
     175           4 :         if (strlen(name) >= IDLENGTH) {
     176           0 :                 throw(SYNTAX, "atomDefinition", "Atom name '%s' too long", name);
     177             :         }
     178           4 :         if (ATOMindex(name) >= 0) {
     179             :                 return MAL_SUCCEED;
     180             :         }
     181           4 :         if (tpe < 0 || tpe >= GDKatomcnt) {
     182           0 :                 throw(TYPE, "atomDefinition", "Undefined atom inheritance '%s'", name);
     183             :         }
     184           4 :         if (strlen(name) >= sizeof(BATatoms[0].name))
     185           0 :                 throw(TYPE, "atomDefinition", "Atom name too long '%s'", name);
     186             : 
     187           4 :         i = ATOMallocate(name);
     188           4 :         if (is_int_nil(i))
     189           0 :                 throw(TYPE, "atomDefinition", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     190             :         /* overload atom ? */
     191           4 :         if (tpe) {
     192           4 :                 BATatoms[i] = BATatoms[tpe];
     193           4 :                 strcpy_len(BATatoms[i].name, name, sizeof(BATatoms[i].name));
     194           4 :                 BATatoms[i].storage = ATOMstorage(tpe);
     195             :         } else {                                        /* cannot overload void atoms */
     196           0 :                 BATatoms[i].storage = i;
     197           0 :                 BATatoms[i].linear = false;
     198             :         }
     199             :         return MAL_SUCCEED;
     200             : }
     201             : 
     202             : /*
     203             :  * User defined modules may introduce fixed sized types
     204             :  * to store information in BATs.
     205             :  */
     206             : int
     207         324 : malAtomSize(int size, const char *name)
     208             : {
     209         324 :         int i = 0;
     210             : 
     211         324 :         i = ATOMindex(name);
     212         324 :         BATatoms[i].storage = i;
     213         324 :         BATatoms[i].size = size;
     214         324 :         assert_shift_width(ATOMelmshift(ATOMsize(i)), ATOMsize(i));
     215         324 :         return i;
     216             : }
     217             : 
     218             : void
     219         334 : mal_atom_reset(void)
     220             : {
     221         334 :         int i;
     222         334 :         for (i = 0; i < GDKatomcnt; i++)
     223             :                 if (BATatoms[i].atomNull) {
     224             :                         // TBD
     225             :                 }
     226         334 : }

Generated by: LCOV version 1.14