Exemplo n.º 1
0
  public void cmdProc(
      Interp interp, // Current interpreter.
      TclObject argv[]) // Argument list.
      throws TclException // Standard Tcl exception.
      {
    // Create the call frame and parameter bindings

    CallFrame frame = interp.newCallFrame(this, argv);

    // Execute the body

    interp.pushDebugStack(srcFileName, srcLineNumber);
    try {
      Parser.eval2(interp, body.array, body.index, body_length, 0);
    } catch (TclException e) {
      int code = e.getCompletionCode();
      if (code == TCL.RETURN) {
        int realCode = interp.updateReturnInfo();
        if (realCode != TCL.OK) {
          e.setCompletionCode(realCode);
          throw e;
        }
      } else if (code == TCL.ERROR) {
        if (this.isLambda()) {
          TclObject name = TclList.newInstance();
          TclList.append(interp, name, argv, 0, 2);
          interp.addErrorInfo(
              "\n    (lambda term \"" + name.toString() + "\" line " + interp.errorLine + ")");
        } else {
          interp.addErrorInfo(
              "\n    (procedure \"" + argv[0] + "\" line " + interp.errorLine + ")");
        }
        throw e;
      } else if (code == TCL.BREAK) {
        throw new TclException(interp, "invoked \"break\" outside of a loop");
      } else if (code == TCL.CONTINUE) {
        throw new TclException(interp, "invoked \"continue\" outside of a loop");
      } else {
        throw e;
      }
    } finally {
      interp.popDebugStack();

      // The check below is a hack. The problem is that there
      // could be unset traces on the variables, which cause
      // scripts to be evaluated. This will clear the
      // errInProgress flag, losing stack trace information if
      // the procedure was exiting with an error. The code
      // below preserves the flag. Unfortunately, that isn't
      // really enough: we really should preserve the errorInfo
      // variable too (otherwise a nested error in the trace
      // script will trash errorInfo). What's really needed is
      // a general-purpose mechanism for saving and restoring
      // interpreter state.

      if (interp.errInProgress) {
        frame.dispose();
        interp.errInProgress = true;
      } else {
        frame.dispose();
      }
    }
  }
Exemplo n.º 2
0
  public Procedure(
      Interp interp, // Current interpreter.
      Namespace ns, // The namespace that the proc is defined in.
      String name, // Name of the procedure.
      TclObject args, // The formal arguments of this procedure.
      TclObject b, // The body of the procedure.
      String sFileName, // Initial value for the srcFileName member.
      int sLineNumber) // Initial value for the srcLineNumber member.
      throws TclException // Standard Tcl exception.
      {
    srcFileName = sFileName;
    srcLineNumber = sLineNumber;

    // Break up the argument list into argument specifiers, then process
    // each argument specifier.

    int numArgs = TclList.getLength(interp, args);
    argList = new TclObject[numArgs][2];

    for (int i = 0; i < numArgs; i++) {
      // Now divide the specifier up into name and default.

      TclObject argSpec = TclList.index(interp, args, i);
      int specLen = TclList.getLength(interp, argSpec);

      if (specLen == 0) {
        // NEM 2010-06-14: updated to match Tcl 8.5+ and [apply]
        throw new TclException(interp, "argument with no name");
      }
      if (specLen > 2) {
        throw new TclException(
            interp, "too many fields in argument " + "specifier \"" + argSpec + "\"");
      }
      TclObject argName = TclList.index(interp, argSpec, 0);
      String argNameStr = argName.toString();
      if (argNameStr.indexOf("::") != -1) {
        // NEM: 2010-06-14: updated to match Tcl 8.5+
        throw new TclException(interp, "formal parameter \"" + argSpec + "\" is not a simple name");
      } else if (Var.isArrayVarname(argNameStr)) {
        // NEM: 2010-06-14: updated to match Tcl 8.5+
        throw new TclException(interp, "formal parameter \"" + argSpec + "\" is an array element");
      }

      argList[i][0] = argName;
      argList[i][0].preserve();
      if (specLen == 2) {
        argList[i][1] = TclList.index(interp, argSpec, 1);
        argList[i][1].preserve();
      } else {
        argList[i][1] = null;
      }
    }

    if (numArgs > 0 && (argList[numArgs - 1][0].toString().equals("args"))) {
      isVarArgs = true;
    } else {
      isVarArgs = false;
    }

    body = new CharPointer(b.toString());
    body_length = body.length();
  }
Exemplo n.º 3
0
  /**
   * Executes a "case" statement. See Tcl user documentation for details.
   *
   * @param interp the current interpreter.
   * @param argv command arguments.
   * @exception TclException If incorrect number of arguments.
   */
  public void cmdProc(Interp interp, TclObject argv[]) throws TclException {
    if (argv.length < 3) {
      throw new TclNumArgsException(interp, 1, argv, "string ?in? patList body ... ?default body?");
    }

    int i, result;
    int body;
    TclObject caseArgv[];
    String string;

    string = argv[1].toString();
    caseArgv = argv;
    body = -1;

    if (argv[2].toString().equals("in")) {
      i = 3;
    } else {
      i = 2;
    }

    /*
     * If all of the pattern/command pairs are lumped into a single
     * argument, split them out again.
     */

    if (argv.length - i == 1) {
      caseArgv = TclList.getElements(interp, argv[i]);
      i = 0;
    }

    match_loop:
    {
      for (; i < caseArgv.length; i += 2) {
        int j;

        if (i == (caseArgv.length - 1)) {
          throw new TclException(interp, "extra case pattern with no body");
        }

        /*
         * Check for special case of single pattern (no list) with
         * no backslash sequences.
         */

        String caseString = caseArgv[i].toString();
        int len = caseString.length();
        for (j = 0; j < len; j++) {
          char c = caseString.charAt(j);
          if (Character.isWhitespace(c) || (c == '\\')) {
            break;
          }
        }
        if (j == len) {
          if (caseString.equals("default")) {
            body = i + 1;
          }
          if (Util.stringMatch(string, caseString)) {
            body = i + 1;
            break match_loop;
          }
          continue;
        }

        /*
         * Break up pattern lists, then check each of the patterns
         * in the list.
         */

        int numPats = TclList.getLength(interp, caseArgv[i]);
        for (j = 0; j < numPats; j++) {
          if (Util.stringMatch(string, TclList.index(interp, caseArgv[i], j).toString())) {
            body = i + 1;
            break match_loop;
          }
        }
      }
    }

    if (body != -1) {
      try {
        interp.eval(caseArgv[body], 0);
      } catch (TclException e) {
        if (e.getCompletionCode() == TCL.ERROR) {
          interp.addErrorInfo(
              "\n    (\"" + caseArgv[body - 1] + "\" arm line " + interp.errorLine + ")");
        }
        throw e;
      }
    }
  }