str instruction2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int flg) { int i; str base, t; size_t len = 512 + (p->argc * 128); /* max realistic line length estimate */ str arg; t = base = GDKmalloc(len); if ( base == NULL) return NULL; if (!flg) { *t++ = '#'; len--; if (p->typechk == TYPE_UNKNOWN) { *t++ = '!'; /* error */ len--; } } *t = 0; if (p->token == REMsymbol && !( getModuleId(p) && strcmp(getModuleId(p),"querylog") == 0 && getFunctionId(p) && strcmp(getFunctionId(p),"define") == 0)) { /* do nothing */ } else if (p->barrier) { if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == RAISEsymbol) { if (!copystring(&t, " ", &len)) return base; } arg = operatorName(p->barrier); if (!copystring(&t, arg, &len) || !copystring(&t, " ", &len)) return base; } else if( functionStart(p) && flg != LIST_MAL_CALL ){ return fcnDefinition(mb, p, t, flg, base, len + (t - base)); } else if (!functionExit(p) && flg!=LIST_MAL_CALL) { // beautify with tabs if (!copystring(&t, " ", &len)) return base; } switch (p->token<0?-p->token:p->token) { case FCNcall: case FACcall: case PATcall: case CMDcall: case ASSIGNsymbol : // is any variable explicit or used for (i = 0; i < p->retc; i++) if ( !isTmpVar(mb,getArg(p,i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i))) break; if (i == p->retc) break; /* display multi-assignment list */ if (p->retc > 1 && !copystring(&t, "(", &len)) return base; for (i = 0; i < p->retc; i++) { arg= renderTerm(mb, stk, p, i, flg); if (arg) { if (!copystring(&t, arg, &len)) { GDKfree(arg); return base; } GDKfree(arg); } if (i < p->retc - 1 && !copystring(&t, ", ", &len)) return base; } if (p->retc > 1 && !copystring(&t, ")", &len)) return base; if (p->argc > p->retc || getFunctionId(p)) { if (!copystring(&t, " := ", &len)) return base; } break; case ENDsymbol: if (!copystring(&t, "end ", &len) || !copystring(&t, getModuleId(getInstrPtr(mb,0)), &len) || !copystring(&t, ".", &len) || !copystring(&t, getFunctionId(getInstrPtr(mb, 0)), &len)) return base; break; case COMMANDsymbol: case FUNCTIONsymbol: case FACTORYsymbol: case PATTERNsymbol: if (flg & LIST_MAL_VALUE) { if (!copystring(&t, operatorName(p->token), &len) || !copystring(&t, " ", &len)) return base; } return fcnDefinition(mb, p, t, flg, base, len + (t - base)); case REMsymbol: case NOOPsymbol: if (!copystring(&t, "#", &len)) return base; if (getVar(mb, getArg(p, 0))->value.val.sval && getVar(mb, getArg(p, 0))->value.len > 0 && !copystring(&t, getVar(mb, getArg(p, 0))->value.val.sval, &len)) return base; if (!copystring(&t, " ", &len)) return base; break; default: i = snprintf(t, len, " unknown symbol ?%d? ", p->token); if (i < 0 || (size_t) i >= len) return base; len -= (size_t) i; t += i; break; } if (getModuleId(p)) { if (!copystring(&t, getModuleId(p), &len) || !copystring(&t, ".", &len)) return base; } if (getFunctionId(p)) { if (!copystring(&t, getFunctionId(p), &len) || !copystring(&t, "(", &len)) return base; } else if (p->argc > p->retc + 1) { if (!copystring(&t, "(", &len)) return base; } for (i = p->retc; i < p->argc; i++) { arg= renderTerm(mb, stk, p, i, flg); if (arg) { if (!copystring(&t, arg, &len)) { GDKfree(arg); return base; } GDKfree(arg); } if (i < p->argc -1 && !copystring(&t, ", ", &len)) return base; } if (getFunctionId(p) || p->argc > p->retc + 1) { if (!copystring(&t, ")", &len)) return base; } if (p->token != REMsymbol){ if (!copystring(&t, ";", &len)) return base; } return base; }
str instruction2str(MalBlkPtr mb, MalStkPtr stk, InstrPtr p, int flg) { int i, tab = 4; str base, s, t; size_t len= (mb->stop < 1000? 1000: mb->stop) * 128 /* max realistic line length estimate */; str arg; base = s = GDKmalloc(len); if ( s == NULL) return s; if (flg) { s[0] = 0; t = s; } else { s[0] = '#'; if (p->typechk == TYPE_UNKNOWN) { s[1] = '!'; /* error */ s[2] = 0; t = s + 2; } else { s[1] = 0; t = s + 1; } } advance(t,base,len); if (p->token == REMsymbol) { /* do nothing */ } else if (p->barrier) { if (p->barrier == LEAVEsymbol || p->barrier == REDOsymbol || p->barrier == RETURNsymbol || p->barrier == YIELDsymbol || p->barrier == RAISEsymbol) { for(;tab>0;tab--) *t++= ' '; *t= 0; advance(t,base,len); } snprintf(t,(len-(t-base)), "%s ", operatorName(p->barrier)); advance(t,base,len); } else if( functionStart(p) && flg != LIST_MAL_CALL ){ return fcnDefinition(mb, p, s, flg, base, len); } else if (!functionExit(p) && flg!=LIST_MAL_CALL) { // beautify with tabs for(;tab>0;tab--) *t++= ' '; *t= 0; advance(t,base,len); } switch (p->token<0?-p->token:p->token) { case FCNcall: case FACcall: case PATcall: case CMDcall: case ASSIGNsymbol : // is any variable explicit or used for (i = 0; i < p->retc; i++) if (!getVarTmp(mb, getArg(p, i)) || isVarUsed(mb, getArg(p, i)) || isVarUDFtype(mb,getArg(p,i))) break; if (i == p->retc) break; /* display multi-assignment list */ if (p->retc > 1) *t++ = '('; for (i = 0; i < p->retc; i++) { arg= renderTerm(mb, stk, p, i, flg); snprintf(t,(len-(t-base)), "%s", arg); GDKfree(arg); advance(t,base,len); if (i < p->retc - 1) *t++ = ','; } if (p->retc > 1) *t++ = ')'; if (p->argc > p->retc || getFunctionId(p)) { sprintf(t, " := "); t += 4; } *t = 0; break; case ENDsymbol: snprintf(t,(len-(t-base)), "end %s.%s", getModuleId(getInstrPtr(mb,0)), getFunctionId(getInstrPtr(mb, 0))); advance(t,base,len); break; case COMMANDsymbol: case FUNCTIONsymbol: case FACTORYsymbol: case PATTERNsymbol: if (flg & LIST_MAL_VALUE) { snprintf(t,(len-(t-base)), "%s ", operatorName(p->token)); advance(t,base,len); break; } return fcnDefinition(mb, p, s, flg, base, len); case REMsymbol: case NOOPsymbol: if(getVar(mb, getArg(p, 0))->value.val.sval) snprintf(t,(len-(t-base)), "#%s ", getVar(mb, getArg(p, 0))->value.val.sval); else snprintf(t, (len-(t-base)), "# "); break; default: snprintf(t, (len-(t-base))," unknown symbol ?%d? ", p->token); } advance(t,base,len); if (getModuleId(p)) snprintf(t, (len-(t-base)),"%s.", getModuleId(p)); advance(t,base,len); if (getFunctionId(p)) { snprintf(t, (len-(t-base)), "%s(", getFunctionId(p)); } else if (p->argc > p->retc + 1) snprintf(t, (len-(t-base)), "("); advance(t,base,len); for (i = p->retc; i < p->argc; i++) { arg= renderTerm(mb, stk, p, i, flg); snprintf(t,(len-(t-base)), "%s", arg); GDKfree(arg); advance(t,base,len); if (i < p->argc -1){ snprintf(t, (len-(t-base)), ","); advance(t,base,len); } } if (getFunctionId(p) || p->argc > p->retc + 1) snprintf(t,(len-(t-base)), ")"); advance(t,base,len); if (p->token != REMsymbol){ snprintf(t,(len-(t-base)), ";"); advance(t,base,len); } /* we may accidentally overwrite */ if (t > s + len) GDKfatal("instruction2str:"); return base; }