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