void Program_xref()

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