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); }
|