LCOV - code coverage report
Current view: top level - monetdb5/modules/mal - inspect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 74 317 23.3 %
Date: 2021-10-27 03:06:47 Functions: 7 21 33.3 %

          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             : /*
      10             :  * author Martin Kersten
      11             :  * Inspection
      12             :  * This module introduces a series of commands that provide access
      13             :  * to information stored within the interpreter data structures.
      14             :  * It's primary use is debugging.
      15             :  * In all cases, the pseudo BAT operation is returned that
      16             :  * should be garbage collected after being used.
      17             :  *
      18             :  * The main performance drain would be to use a pseudo BAT directly to
      19             :  * successively access it components. This can be avoided by first assigning
      20             :  * the pseudo BAT to a variable.
      21             :  */
      22             : #include "monetdb_config.h"
      23             : #include "gdk.h"
      24             : #include <time.h>
      25             : #include "mal_resolve.h"
      26             : #include "mal_client.h"
      27             : #include "mal_exception.h"
      28             : #include "mal_debugger.h"
      29             : #include "mal_interpreter.h"
      30             : #include "mal_listing.h"
      31             : #include "mal_namespace.h"
      32             : 
      33             : static int
      34           3 : pseudo(bat *ret, BAT *b, str X1,str X2, str X3) {
      35             :         char buf[BUFSIZ];
      36           3 :         snprintf(buf,BUFSIZ,"%s_%s_%s", X1,X2,X3);
      37           3 :         if (BBPindex(buf) <= 0 && BBPrename(b->batCacheid, buf) != 0)
      38             :                 return -1;
      39           3 :         if (BATroles(b,X2) != GDK_SUCCEED)
      40             :                 return -1;
      41           3 :         *ret = b->batCacheid;
      42           3 :         BBPkeepref(*ret);
      43           3 :         return 0;
      44             : }
      45             : 
      46             : /*
      47             :  * Symbol table
      48             :  * Mal symbol table and environment analysis.
      49             :  *
      50             :  * Collect symbol table information in a series of BATs for analysis
      51             :  * and display. Note, the elements are aligned using a counter,
      52             :  * which makes it susceptable for intermediate updates
      53             :  */
      54             : 
      55             : static str
      56           0 : INSPECTgetAllFunctions(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      57             : {
      58             :         Module s;
      59             :         Symbol t;
      60             :         int i, j;
      61             :         Module* moduleList;
      62             :         int length;
      63           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
      64           0 :         bat *ret = getArgReference_bat(stk,pci,0);
      65             : 
      66             :         (void) mb;
      67           0 :         if (b == 0)
      68           0 :                 throw(MAL, "inspect.getgetFunctionId", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      69             : 
      70           0 :         getModuleList(&moduleList, &length);
      71           0 :         if (moduleList == NULL)
      72           0 :                 goto bailout;
      73           0 :         for(j = -1; j < length; j++) {
      74           0 :                 s = j < 0 ? cntxt->usermodule : moduleList[j];
      75           0 :                 for (i = 0; s && i < MAXSCOPE; i++) {
      76           0 :                         if (s->space[i]) {
      77           0 :                                 for (t = s->space[i]; t; t = t->peer) {
      78           0 :                                         InstrPtr sig = getSignature(t);
      79           0 :                                         if (BUNappend(b, getFunctionId(sig), false) != GDK_SUCCEED)
      80           0 :                                                 goto bailout;
      81             :                                 }
      82             :                         }
      83             :                 }
      84             :         }
      85           0 :         if (pseudo(ret,b,"view","symbol","function"))
      86           0 :                 goto bailout;
      87           0 :         freeModuleList(moduleList);
      88             : 
      89           0 :         return MAL_SUCCEED;
      90           0 :   bailout:
      91           0 :         BBPreclaim(b);
      92           0 :         freeModuleList(moduleList);
      93           0 :         throw(MAL, "inspect.getgetFunctionId", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      94             : }
      95             : 
      96             : static str
      97           0 : INSPECTgetAllModules(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      98             : {
      99             :         Module s;
     100             :         Symbol t;
     101             :         int i, j;
     102             :         Module* moduleList;
     103             :         int length;
     104           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     105           0 :         bat *ret = getArgReference_bat(stk,pci,0);
     106             : 
     107             :         (void) mb;
     108           0 :         if (b == 0)
     109           0 :                 throw(MAL, "inspect.getmodule", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     110             : 
     111           0 :         getModuleList(&moduleList, &length);
     112           0 :         if (moduleList == NULL)
     113           0 :                 goto bailout;
     114           0 :         for(j = -1; j < length; j++) {
     115           0 :                 s = j < 0 ? cntxt->usermodule : moduleList[j];
     116           0 :                 for (i = 0; s && i < MAXSCOPE; i++) {
     117           0 :                         if (s->space[i]) {
     118           0 :                                 for (t = s->space[i]; t; t = t->peer) {
     119           0 :                                         InstrPtr sig = getSignature(t);
     120             : 
     121           0 :                                         if (BUNappend(b, getModuleId(sig), false) != GDK_SUCCEED)
     122           0 :                                                 goto bailout;
     123             :                                 }
     124             :                         }
     125             :                 }
     126             :         }
     127           0 :         if (pseudo(ret,b,"view","symbol","module"))
     128           0 :                 goto bailout;
     129           0 :         freeModuleList(moduleList);
     130             : 
     131           0 :         return MAL_SUCCEED;
     132           0 :   bailout:
     133           0 :         freeModuleList(moduleList);
     134           0 :         BBPreclaim(b);
     135           0 :         throw(MAL, "inspect.getmodule", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     136             : }
     137             : 
     138             : static str
     139           0 : INSPECTgetkind(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     140             : {
     141             :         Module s;
     142             :         Symbol t;
     143             :         int i, j;
     144             :         Module* moduleList;
     145             :         int length;
     146           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     147           0 :         bat *ret = getArgReference_bat(stk,pci,0);
     148             : 
     149             :         (void)mb;
     150           0 :         if (b == 0)
     151           0 :                 throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     152             : 
     153           0 :         getModuleList(&moduleList, &length);
     154           0 :         if (moduleList == NULL)
     155           0 :                 goto bailout;
     156           0 :         for(j = -1; j < length; j++) {
     157           0 :                 s = j < 0 ? cntxt->usermodule : moduleList[j];
     158           0 :                 for (i = 0; s && i < MAXSCOPE; i++) {
     159           0 :                         if (s->space[i]) {
     160           0 :                                 for (t = s->space[i]; t; t = t->peer) {
     161           0 :                                         InstrPtr sig = getSignature(t);
     162           0 :                                         str kind = operatorName(sig->token);
     163           0 :                                         if (BUNappend(b, kind, false) != GDK_SUCCEED)
     164           0 :                                                 goto bailout;
     165             :                                 }
     166             :                         }
     167             :                 }
     168             :         }
     169           0 :         if (pseudo(ret,b,"view","symbol","kind"))
     170           0 :                 goto bailout;
     171           0 :         freeModuleList(moduleList);
     172             : 
     173           0 :         return MAL_SUCCEED;
     174           0 :   bailout:
     175           0 :         BBPreclaim(b);
     176           0 :         freeModuleList(moduleList);
     177           0 :         throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     178             : }
     179             : 
     180             : static str
     181           0 : INSPECTgetAllSignatures(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     182             : {
     183             :         Module s;
     184             :         Symbol t;
     185             :         int i, j;
     186             :         Module* moduleList;
     187             :         int length;
     188           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     189             :         char sig[BLOCK],*a;
     190           0 :         bat *ret = getArgReference_bat(stk,pci,0);
     191             : 
     192             :         (void)mb;
     193           0 :         if (b == 0)
     194           0 :                 throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     195             : 
     196           0 :         getModuleList(&moduleList, &length);
     197           0 :         if (moduleList == NULL)
     198           0 :                 goto bailout;
     199           0 :         for(j = -1; j < length; j++) {
     200           0 :                 s = j < 0 ? cntxt->usermodule : moduleList[j];
     201           0 :                 for (i = 0; s && i < MAXSCOPE; i++)
     202           0 :                         if (s->space[i]) {
     203           0 :                                 for (t = s->space[i]; t; t = t->peer) {
     204           0 :                                         fcnDefinition(t->def, getSignature(t), sig, 0,sig,BLOCK);
     205           0 :                                         a= strstr(sig,"address");
     206           0 :                                         if(a) *a = 0;
     207           0 :                                         if (BUNappend(b, (a = strchr(sig, '(')) ? a : "", false) != GDK_SUCCEED)
     208           0 :                                                 goto bailout;
     209             :                                 }
     210             :                         }
     211             :         }
     212           0 :         if (pseudo(ret,b,"view"," symbol","address"))
     213           0 :                 goto bailout;
     214           0 :         freeModuleList(moduleList);
     215             : 
     216           0 :         return MAL_SUCCEED;
     217           0 :   bailout:
     218           0 :         BBPreclaim(b);
     219           0 :         freeModuleList(moduleList);
     220           0 :         throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     221             : }
     222             : 
     223             : #if 0
     224             : static str
     225             : INSPECTgetAllAddresses(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     226             : {
     227             :         Module s;
     228             :         Symbol t;
     229             :         int i, j;
     230             :         Module* moduleList;
     231             :         int length;
     232             :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     233             :         char sig[BLOCK],*a;
     234             :         bat *ret = getArgReference_bat(stk,pci,0);
     235             : 
     236             :         (void)mb;
     237             : 
     238             :         if (b == 0)
     239             :                 throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     240             : 
     241             :         getModuleList(&moduleList, &length);
     242             :         if (moduleList == NULL)
     243             :                 goto bailout;
     244             :         for(j = -1; j < length; j++) {
     245             :                 s = j < 0 ? cntxt->usermodule : moduleList[j];
     246             :                 for (i = 0; s && i < MAXSCOPE; i++)
     247             :                         if (s->space[i]) {
     248             :                                 for (t = s->space[i]; t; t = t->peer) {
     249             :                                         fcnDefinition(t->def, getSignature(t), sig, 0,sig,BLOCK);
     250             :                                         a= strstr(sig,"address");
     251             :                                         if( a)
     252             :                                                 for( a=a+7; isspace((unsigned char) *a); a++)
     253             :                                                         ;
     254             :                                         if (BUNappend(b, (a? a: "nil"), false) != GDK_SUCCEED)
     255             :                                                 goto bailout;
     256             :                                 }
     257             :                         }
     258             :         }
     259             :         if (pseudo(ret,b,"view"," symbol","address"))
     260             :                 goto bailout;
     261             :         freeModuleList(moduleList);
     262             : 
     263             :         return MAL_SUCCEED;
     264             :   bailout:
     265             :         BBPreclaim(b);
     266             :         freeModuleList(moduleList);
     267             :         throw(MAL, "inspect.get", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     268             : }
     269             : #endif
     270             : 
     271             : static str
     272           0 : INSPECTgetDefinition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     273             : {
     274           0 :         bat *ret = getArgReference_bat(stk,pci,0);
     275           0 :         str *mod = getArgReference_str(stk,pci,1);
     276           0 :         str *fcn = getArgReference_str(stk,pci,2);
     277             :         Symbol s;
     278             :         BAT *b;
     279             :         (void)mb;
     280             : 
     281           0 :         s = findSymbol(cntxt->usermodule, putName(*mod), putName(*fcn));
     282           0 :         if (s == 0)
     283           0 :                 throw(MAL, "inspect.getDefinition", RUNTIME_SIGNATURE_MISSING);
     284             : 
     285           0 :         b = COLnew(0, TYPE_str, 256, TRANSIENT);
     286           0 :         if (b == 0)
     287           0 :                 throw(MAL, "inspect.getDefinition", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     288             : 
     289           0 :         while (s) {
     290             :                 int i;
     291             :                 str ps;
     292             : 
     293           0 :                 for (i = 0; i < s->def->stop; i++) {
     294           0 :                         if((ps = instruction2str(s->def,0, getInstrPtr(s->def, i), 0)) == NULL)
     295           0 :                                 goto bailout;
     296           0 :                         if (BUNappend(b, ps + 1, false) != GDK_SUCCEED) {
     297           0 :                                 GDKfree(ps);
     298           0 :                                 goto bailout;
     299             :                         }
     300           0 :                         GDKfree(ps);
     301             :                 }
     302           0 :                 s = s->peer;
     303             :         }
     304           0 :         if (pseudo(ret,b,"view","fcn","stmt"))
     305           0 :                 goto bailout;
     306             : 
     307             :         return MAL_SUCCEED;
     308           0 :   bailout:
     309           0 :         BBPreclaim(b);
     310           0 :         throw(MAL, "inspect.getDefinition", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     311             : }
     312             : 
     313             : static str
     314           0 : INSPECTgetExistence(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     315             : {
     316             :         (void) mb;
     317             : 
     318           0 :         bit *ret = getArgReference_bit(stk,pci,0);
     319           0 :         str *mod = getArgReference_str(stk,pci,1);
     320           0 :         str *fcn = getArgReference_str(stk,pci,2);
     321             : 
     322           0 :         Symbol s = findSymbol(cntxt->usermodule, getName(*mod), putName(*fcn));
     323             : 
     324           0 :         *ret = (s != NULL);
     325             : 
     326           0 :         return MAL_SUCCEED;
     327             : }
     328             : 
     329             : static str
     330           3 : INSPECTgetSignature(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     331             : {
     332           3 :         bat *ret = getArgReference_bat(stk,pci,0);
     333           3 :         str *mod = getArgReference_str(stk,pci,1);
     334           3 :         str *fcn = getArgReference_str(stk,pci,2);
     335             :         Symbol s;
     336             :         str ps, tail;
     337             :         BAT *b;
     338             :         (void) mb;
     339             : 
     340           3 :         s = findSymbol(cntxt->usermodule, getName(*mod), putName(*fcn));
     341           3 :         if (s == 0)
     342           0 :                 throw(MAL, "inspect.getSignature", RUNTIME_SIGNATURE_MISSING);
     343           3 :         b = COLnew(0, TYPE_str, 12, TRANSIENT);
     344           3 :         if (b == 0)
     345           0 :                 throw(MAL, "inspect.getSignature", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     346             : 
     347           7 :         while (s != NULL) {
     348           4 :                 if (idcmp(s->name, *fcn) == 0) {
     349           4 :                         InstrPtr p = getSignature(s);
     350             :                         char *c, *w;
     351             : 
     352           4 :                         ps = instruction2str(s->def, 0, p, 0);
     353           4 :                         if (ps == 0) {
     354           0 :                                 continue;
     355             :                         }
     356           4 :                         c = strchr(ps, '(');
     357           4 :                         if (c == 0) {
     358           0 :                                 GDKfree(ps);
     359           0 :                                 continue;
     360             :                         }
     361           4 :                         tail= strstr(c,"address");
     362           4 :                         if( tail)
     363           0 :                                 *tail = 0;
     364           4 :                         if (tail && (w=strchr(tail, ';')) )
     365           0 :                                 *w = 0;
     366           4 :                         if (BUNappend(b, c, false) != GDK_SUCCEED) {
     367           0 :                                 GDKfree(ps);
     368           0 :                                 goto bailout;
     369             :                         }
     370           4 :                         GDKfree(ps);
     371             :                 }
     372           4 :                 s = s->peer;
     373             :         }
     374             : 
     375           3 :         if (pseudo(ret,b,"view","input","result"))
     376           0 :                 goto bailout;
     377             :         return MAL_SUCCEED;
     378           0 :   bailout:
     379           0 :         BBPreclaim(b);
     380           0 :         throw(MAL, "inspect.getSignature", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     381             : }
     382             : 
     383             : static str
     384           0 : INSPECTgetComment(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     385             : {
     386           0 :         bat *ret = getArgReference_bat(stk,pci,0);
     387           0 :         str *mod = getArgReference_str(stk,pci,1);
     388           0 :         str *fcn = getArgReference_str(stk,pci,2);
     389             :         Symbol s;
     390             :         BAT *b;
     391             :         (void) mb;
     392             : 
     393           0 :         s = findSymbol(cntxt->usermodule, getName(*mod), putName(*fcn));
     394           0 :         if (s == 0)
     395           0 :                 throw(MAL, "inspect.getComment", RUNTIME_SIGNATURE_MISSING);
     396           0 :         b = COLnew(0, TYPE_str, 12, TRANSIENT);
     397           0 :         if (b == 0)
     398           0 :                 throw(MAL, "inspect.getComment", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     399             : 
     400           0 :         while (s != NULL) {
     401           0 :                 if (idcmp(s->name, *fcn) == 0 &&
     402           0 :                         BUNappend(b, s->def->help, false) != GDK_SUCCEED)
     403           0 :                         goto bailout;
     404           0 :                 s = s->peer;
     405             :         }
     406             : 
     407           0 :         if (pseudo(ret,b,"view","input","result"))
     408           0 :                 goto bailout;
     409             :         return MAL_SUCCEED;
     410           0 :   bailout:
     411           0 :         BBPreclaim(b);
     412           0 :         throw(MAL, "inspect.getComment", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     413             : }
     414             : 
     415             : static str
     416           1 : INSPECTgetSource(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     417             : {
     418           1 :         str *ret = getArgReference_str(stk,pci,0);
     419           1 :         str *mod = getArgReference_str(stk,pci,1);
     420           1 :         str *fcn = getArgReference_str(stk,pci,2);
     421             :         Symbol s;
     422             :         char *buf;
     423             :         size_t len,lim;
     424             :         (void) mb;
     425             : 
     426           1 :         s = findSymbol( cntxt->usermodule, getName(*mod), putName(*fcn));
     427           1 :         if (s == 0)
     428           0 :                 throw(MAL, "inspect.getSource", RUNTIME_SIGNATURE_MISSING);
     429             : 
     430           1 :         buf= (char*) GDKmalloc(BUFSIZ);
     431           1 :         if ( buf == NULL)
     432           0 :                 throw(MAL, "inspect.getSource", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     433           1 :         snprintf(buf,BUFSIZ,"%s.%s",*mod,*fcn);
     434           1 :         buf[0]=0;
     435             :         len= 0;
     436             :         lim= BUFSIZ;
     437             : 
     438           2 :         while (s) {
     439             :                 int i;
     440             :                 str ps;
     441             : 
     442           8 :                 for (i = 0; i < s->def->stop; i++) {
     443           7 :                         if((ps = instruction2str(s->def, 0, getInstrPtr(s->def, i), LIST_MAL_NAME )) == NULL) {
     444           0 :                                 GDKfree(buf);
     445           0 :                                 throw(MAL, "inspect.getSource", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     446             :                         }
     447           7 :                         if( strlen(ps) >= lim-len){
     448             :                                 /* expand the buffer */
     449             :                                 char *bn;
     450           0 :                                 bn= GDKrealloc(buf, lim+BUFSIZ);
     451           0 :                                 if ( bn == NULL) {
     452           0 :                                         GDKfree(ps);
     453           0 :                                         GDKfree(buf);
     454           0 :                                         throw(MAL, "inspect.getSource", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     455             :                                 }
     456             :                                 buf=bn;
     457             :                                 lim+= BUFSIZ;
     458             :                         }
     459           7 :                         strcat(buf+len,ps);
     460           7 :                         len+= strlen(ps);
     461           7 :                         buf[len++]='\n';
     462           7 :                         buf[len]=0;
     463           7 :                         GDKfree(ps);
     464             :                 }
     465           1 :                 s = s->peer;
     466             :         }
     467           1 :         *ret= buf;
     468           1 :         return MAL_SUCCEED;
     469             : }
     470             : 
     471             : static str
     472           0 : INSPECTatom_names(bat *ret)
     473             : {
     474             :         int i;
     475           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     476             : 
     477           0 :         if (b == 0)
     478           0 :                 throw(MAL, "inspect.getAtomNames", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     479             : 
     480           0 :         for (i = 0; i < GDKatomcnt; i++)
     481           0 :                 if (BUNappend(b, ATOMname(i), false) != GDK_SUCCEED)
     482           0 :                         goto bailout;
     483             : 
     484           0 :         if (pseudo(ret,b,"view","atom","name"))
     485           0 :                 goto bailout;
     486             : 
     487             :         return MAL_SUCCEED;
     488           0 :   bailout:
     489           0 :         BBPreclaim(b);
     490           0 :         throw(MAL, "inspect.getAtomNames", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     491             : }
     492             : 
     493             : static str
     494          36 : INSPECTgetEnvironment(bat *ret, bat *ret2)
     495             : {
     496             :         BAT *k, *v;
     497             : 
     498          36 :         if (GDKcopyenv(&k, &v, false) != GDK_SUCCEED)
     499           0 :                 throw(MAL, "inspect.getEnvironment", GDK_EXCEPTION);
     500             : 
     501          36 :         BBPkeepref(*ret = k->batCacheid);
     502          36 :         BBPkeepref(*ret2 = v->batCacheid);
     503          36 :         return MAL_SUCCEED;
     504             : }
     505             : 
     506             : static str
     507           6 : INSPECTgetEnvironmentKey(str *ret, str *key)
     508             : {
     509             :         const char *s;
     510           6 :         *ret = 0;
     511             : 
     512           6 :         s= GDKgetenv(*key);
     513           6 :         if (s == 0)
     514           0 :                 s= getenv(*key);
     515           6 :         if (s == 0)
     516           0 :                 throw(MAL, "inspect.getEnvironment", "environment variable '%s' not found", *key);
     517           6 :         *ret = GDKstrdup(s);
     518           6 :         if (*ret == NULL)
     519           0 :                 throw(MAL, "inspect.getEnvironment", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     520             :         return MAL_SUCCEED;
     521             : }
     522             : 
     523             : static str
     524           0 : INSPECTatom_sup_names(bat *ret)
     525             : {
     526             :         int i, k;
     527           0 :         BAT *b = COLnew(0, TYPE_str, 256, TRANSIENT);
     528             : 
     529           0 :         if (b == 0)
     530           0 :                 throw(MAL, "inspect.getAtomSuper", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     531             : 
     532           0 :         for (i = 0; i < GDKatomcnt; i++) {
     533           0 :                 for (k = ATOMstorage(i); k > TYPE_str; k = ATOMstorage(k))
     534             :                         ;
     535           0 :                 if (BUNappend(b, ATOMname(k), false) != GDK_SUCCEED)
     536           0 :                         goto bailout;
     537             :         }
     538             : 
     539           0 :         if (pseudo(ret,b,"view","atom","sup_name"))
     540           0 :                 goto bailout;
     541             : 
     542             :         return MAL_SUCCEED;
     543           0 :   bailout:
     544           0 :         BBPreclaim(b);
     545           0 :         throw(MAL, "inspect.getAtomSuper", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     546             : }
     547             : 
     548             : static str
     549           0 : INSPECTatom_sizes(bat *ret)
     550             : {
     551             :         int i;
     552             :         int s;
     553           0 :         BAT *b = COLnew(0, TYPE_int, 256, TRANSIENT);
     554             : 
     555           0 :         if (b == 0)
     556           0 :                 throw(MAL, "inspect.getAtomSizes", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     557             : 
     558           0 :         for (i = 0; i < GDKatomcnt; i++) {
     559           0 :                 s = ATOMsize(i);
     560           0 :                 if (BUNappend(b, &s, false) != GDK_SUCCEED)
     561           0 :                         goto bailout;
     562             :         }
     563             : 
     564           0 :         if (pseudo(ret,b,"view","atom","size"))
     565           0 :                 goto bailout;
     566             : 
     567             :         return MAL_SUCCEED;
     568           0 :   bailout:
     569           0 :         BBPreclaim(b);
     570           0 :         throw(MAL, "inspect.getAtomSizes", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     571             : }
     572             : 
     573             : /* calculate to trimmed storage space */
     574             : static lng
     575           0 : INSPECTcalcSize(MalBlkPtr mb){
     576             :         lng size,args=0,i;
     577             :         InstrPtr p;
     578             : 
     579           0 :         for(i=0;i<mb->stop; i++){
     580           0 :                 p= getInstrPtr(mb,i);
     581           0 :                 args += (p->argc-1)* sizeof(*p->argv);
     582             :         }
     583           0 :         size = (offsetof(InstrRecord, argv) +sizeof(InstrPtr)) * mb->stop;
     584           0 :         size += sizeof(VarRecord) * mb->vtop;
     585           0 :         size += args;
     586           0 :         return size;
     587             : }
     588             : 
     589             : static str
     590           0 : INSPECTgetSize(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p){
     591           0 :         lng *ret = getArgReference_lng(stk,p,0);
     592             : 
     593             : 
     594           0 :         *ret= INSPECTcalcSize(mb);
     595             :         (void) cntxt;
     596             :         (void) mb;
     597           0 :         return MAL_SUCCEED;
     598             : }
     599             : 
     600             : static str
     601           0 : INSPECTgetFunctionSize(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     602             : {
     603           0 :         lng *ret = getArgReference_lng(stk,pci,0);
     604           0 :         str *mod = getArgReference_str(stk,pci,1);
     605           0 :         str *fcn = getArgReference_str(stk,pci,2);
     606             :         Symbol s;
     607             :         (void) mb;
     608             : 
     609           0 :         s = findSymbol(cntxt->usermodule, getName(*mod), putName(*fcn));
     610           0 :         if (s == 0)
     611           0 :                 throw(MAL, "inspect.getSize", RUNTIME_SIGNATURE_MISSING);
     612           0 :         *ret= INSPECTcalcSize(s->def);
     613           0 :         return MAL_SUCCEED;
     614             : }
     615             : /*
     616             :  * Display routines
     617             :  */
     618             : 
     619             : #if 0
     620             : static str
     621             : INSPECTshowFunction(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
     622             : {
     623             :         (void) p;
     624             :         printFunction(cntxt->fdout, mb, stk, LIST_INPUT);
     625             :         return MAL_SUCCEED;
     626             : }
     627             : 
     628             : static str
     629             : INSPECTshowFunction3(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p)
     630             : {
     631             :         str modnme = getArgName(mb, p, 1);
     632             :         str fcnnme = getArgName(mb, p, 2);
     633             :         Symbol s = NULL;
     634             : 
     635             :         s = findSymbol(cntxt->usermodule,getName(modnme), putName(fcnnme));
     636             : 
     637             :         if (s == NULL){
     638             :                 char buf[BUFSIZ];
     639             :                 snprintf(buf,BUFSIZ,"%s.%s", modnme, fcnnme);
     640             :                 throw(MAL, "inspect.showSource",RUNTIME_SIGNATURE_MISSING "%s",buf);
     641             :         } else
     642             :                 printFunction(cntxt->fdout, s->def, stk, LIST_INPUT);
     643             :         return MAL_SUCCEED;
     644             : }
     645             : #endif
     646             : 
     647             : static str
     648           0 : INSPECTequalType(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     649             : {
     650             :         bit *ret;
     651             :         (void) stk;
     652             :         (void) cntxt;
     653           0 :         ret = getArgReference_bit(stk, pci, 0);
     654           0 :         *ret = getArgType(mb,pci,1)== getArgType(mb,pci,2);
     655           0 :         return MAL_SUCCEED;
     656             : }
     657             : 
     658             : static str
     659           7 : INSPECTtypeName(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     660             : {
     661             :         str *hn, *tn =0;
     662             : 
     663           7 :         hn = getArgReference_str(stk, pci, 0);
     664             : 
     665             :         (void) cntxt;
     666           7 :         if( pci->retc== 2){
     667           0 :                 tn = getArgReference_str(stk, pci, 1);
     668           0 :                 *hn = getTypeName(TYPE_oid);
     669           0 :                 *tn = getTypeName(getBatType(getArgType(mb, pci, 2)));
     670           7 :         } else if (isaBatType(getArgType(mb,pci,1) ) ){
     671           1 :                 bat *bid= getArgReference_bat(stk,pci,1);
     672             :                 BAT *b;
     673           1 :                 if ((b = BBPquickdesc(*bid)))
     674           1 :                         *hn = getTypeName(newBatType(b->ttype));
     675             :                 else
     676           0 :                         *hn = getTypeName(getArgType(mb, pci, 1));
     677             :         } else
     678           6 :                 *hn = getTypeName(getArgType(mb, pci, 1));
     679           7 :         return MAL_SUCCEED;
     680             : }
     681             : 
     682             : #include "mel.h"
     683             : mel_func inspect_init_funcs[] = {
     684             :  pattern("inspect", "getDefinition", INSPECTgetDefinition, false, "Returns a string representation of a specific function.", args(1,3, batarg("",str),arg("mod",str),arg("fcn",str))),
     685             :  pattern("inspect", "getExistence", INSPECTgetExistence, false, "Returns a boolean indicating existence of a definition of a specific function.", args(1,3, arg("",bit),arg("mod",str),arg("fcn",str))),
     686             :  pattern("inspect", "getSignature", INSPECTgetSignature, false, "Returns the function signature(s).", args(1,3, batarg("",str),arg("mod",str),arg("fcn",str))),
     687             :  pattern("inspect", "getComment", INSPECTgetComment, false, "Returns the function help information.", args(1,3, batarg("",str),arg("mod",str),arg("fcn",str))),
     688             :  pattern("inspect", "getSource", INSPECTgetSource, false, "Return the original input for a function.", args(1,3, arg("",str),arg("mod",str),arg("fcn",str))),
     689             :  pattern("inspect", "getKind", INSPECTgetkind, false, "Obtain the instruction kind.", args(1,1, batarg("",str))),
     690             :  pattern("inspect", "getModule", INSPECTgetAllModules, false, "Obtain the function name.", args(1,1, batarg("",str))),
     691             :  pattern("inspect", "getFunction", INSPECTgetAllFunctions, false, "Obtain the function name.", args(1,1, batarg("",str))),
     692             :  pattern("inspect", "getSignatures", INSPECTgetAllSignatures, false, "Obtain the function signatures.", args(1,1, batarg("",str))),
     693             :  pattern("inspect", "getSize", INSPECTgetSize, false, "Return the storage size for the current function (in bytes).", args(1,1, arg("",lng))),
     694             :  pattern("inspect", "getSize", INSPECTgetFunctionSize, false, "Return the storage size for a function (in bytes).", args(1,3, arg("",lng),arg("mod",str),arg("fcn",str))),
     695             :  pattern("inspect", "getType", INSPECTtypeName, false, "Return the concrete type of a variable (expression).", args(1,2, arg("",str),argany("v",1))),
     696             :  pattern("inspect", "equalType", INSPECTequalType, false, "Return true if both operands are of the same type", args(1,3, arg("",bit),argany("l",0),argany("r",0))),
     697             :  command("inspect", "getAtomNames", INSPECTatom_names, false, "Collect a BAT with the atom names.", args(1,1, batarg("",str))),
     698             :  command("inspect", "getAtomSuper", INSPECTatom_sup_names, false, "Collect a BAT with the atom names.", args(1,1, batarg("",str))),
     699             :  command("inspect", "getAtomSizes", INSPECTatom_sizes, false, "Collect a BAT with the atom sizes.", args(1,1, batarg("",int))),
     700             :  command("inspect", "getEnvironment", INSPECTgetEnvironment, false, "Collect the environment variables.", args(2,2, batarg("k",str),batarg("v",str))),
     701             :  command("inspect", "getEnvironment", INSPECTgetEnvironmentKey, false, "Get the value of an environemnt variable", args(1,2, arg("",str),arg("k",str))),
     702             :  { .imp=NULL }
     703             : };
     704             : #include "mal_import.h"
     705             : #ifdef _MSC_VER
     706             : #undef read
     707             : #pragma section(".CRT$XCU",read)
     708             : #endif
     709         257 : LIB_STARTUP_FUNC(init_inspect_mal)
     710         257 : { mal_module("inspect", NULL, inspect_init_funcs); }

Generated by: LCOV version 1.14