in interpreters/bas/bas_program.c [948:1120]
void Program_xref(struct Program *this, int chn)
{
struct Pc pc;
struct Xref *func;
struct Xref *var;
struct Xref *gosub;
struct Xref *goto_;
int nl = 0;
assert(this->runnable);
func = (struct Xref *)0;
var = (struct Xref *)0;
gosub = (struct Xref *)0;
goto_ = (struct Xref *)0;
for (pc.line = 0; pc.line < this->size; ++pc.line)
{
struct On *on;
for (on = (struct On *)0, pc.token = this->code[pc.line];
pc.token->type != T_EOL; ++pc.token)
{
switch (pc.token->type)
{
case T_ON:
{
on = &pc.token->u.on;
break;
}
case T_GOTO:
{
if (on)
{
int key;
for (key = 0; key < on->pcLength; ++key)
Xref_add(&goto_, cmpLine, &on->pc[key], &pc);
on = (struct On *)0;
}
else
Xref_add(&goto_, cmpLine, &pc.token->u.gotopc, &pc);
break;
}
case T_GOSUB:
{
if (on)
{
int key;
for (key = 0; key < on->pcLength; ++key)
Xref_add(&gosub, cmpLine, &on->pc[key], &pc);
on = (struct On *)0;
}
else
Xref_add(&gosub, cmpLine, &pc.token->u.gosubpc, &pc);
break;
}
case T_DEFFN:
case T_DEFPROC:
case T_FUNCTION:
case T_SUB:
{
++pc.token;
Xref_add(&func, cmpName, &pc.token->u.identifier->name, &pc);
break;
}
default:
break;
}
}
}
for (pc.line = 0; pc.line < this->size; ++pc.line)
{
for (pc.token = this->code[pc.line]; pc.token->type != T_EOL;
++pc.token)
{
switch (pc.token->type)
{
case T_DEFFN:
case T_DEFPROC:
case T_FUNCTION:
case T_SUB: /* skip identifier already added above */
{
++pc.token;
break;
}
case T_IDENTIFIER:
{
/* formal parameters have no assigned symbol */
if (pc.token->u.identifier->sym)
{
switch (pc.token->u.identifier->sym->type)
{
case GLOBALVAR:
{
Xref_add(&var, cmpName,
&pc.token->u.identifier->name, &pc);
break;
}
case USERFUNCTION:
{
Xref_add(&func, cmpName,
&pc.token->u.identifier->name, &pc);
break;
}
default:
break;
}
}
break;
}
default:
break;
}
}
}
if (func)
{
FS_putChars(chn, _("Function Referenced in line\n"));
Xref_print(func, printName, this, chn);
Xref_destroy(func);
nl = 1;
}
if (var)
{
if (nl)
{
FS_putChar(chn, '\n');
}
FS_putChars(chn, _("Variable Referenced in line\n"));
Xref_print(var, printName, this, chn);
Xref_destroy(func);
nl = 1;
}
if (gosub)
{
if (nl)
{
FS_putChar(chn, '\n');
}
FS_putChars(chn, _("Gosub Referenced in line\n"));
Xref_print(gosub, printLine, this, chn);
Xref_destroy(gosub);
nl = 1;
}
if (goto_)
{
if (nl)
{
FS_putChar(chn, '\n');
}
FS_putChars(chn, _("Goto Referenced in line\n"));
Xref_print(goto_, printLine, this, chn);
Xref_destroy(goto_);
}
}