001: /*
002: * SubstCmd.java
003: *
004: * Copyright (c) 1997 Sun Microsystems, Inc.
005: *
006: * See the file "license.terms" for information on usage and
007: * redistribution of this file, and for a DISCLAIMER OF ALL
008: * WARRANTIES.
009: *
010: * RCS: @(#) $Id: SubstCmd.java,v 1.5 2007/06/07 02:35:26 mdejong Exp $
011: *
012: */
013:
014: package tcl.lang;
015:
016: import java.util.*;
017:
018: /**
019: * This class implements the built-in "subst" command in Tcl.
020: */
021:
022: class SubstCmd implements Command {
023: static final private String validCmds[] = { "-nobackslashes",
024: "-nocommands", "-novariables" };
025:
026: static final int OPT_NOBACKSLASHES = 0;
027: static final int OPT_NOCOMMANDS = 1;
028: static final int OPT_NOVARS = 2;
029:
030: /**
031: * This procedure is invoked to process the "subst" Tcl command.
032: * See the user documentation for details on what it does.
033: *
034: * @param interp the current interpreter.
035: * @param argv command arguments.
036: * @exception TclException if wrong # of args or invalid argument(s).
037: */
038:
039: public void cmdProc(Interp interp, TclObject argv[])
040: throws TclException {
041: int currentObjIndex, len, i;
042: int objc = argv.length - 1;
043: boolean doBackslashes = true;
044: boolean doCmds = true;
045: boolean doVars = true;
046: StringBuffer result = new StringBuffer();
047: String s;
048: char c;
049:
050: for (currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++) {
051: if (!argv[currentObjIndex].toString().startsWith("-")) {
052: break;
053: }
054: int opt = TclIndex.get(interp, argv[currentObjIndex],
055: validCmds, "switch", 0);
056: switch (opt) {
057: case OPT_NOBACKSLASHES:
058: doBackslashes = false;
059: break;
060: case OPT_NOCOMMANDS:
061: doCmds = false;
062: break;
063: case OPT_NOVARS:
064: doVars = false;
065: break;
066: default:
067: throw new TclException(interp,
068: "SubstCmd.cmdProc: bad option " + opt
069: + " index to cmds");
070: }
071: }
072: if (currentObjIndex != objc) {
073: throw new TclNumArgsException(interp, currentObjIndex,
074: argv,
075: "?-nobackslashes? ?-nocommands? ?-novariables? string");
076: }
077:
078: /*
079: * Scan through the string one character at a time, performing
080: * command, variable, and backslash substitutions.
081: */
082:
083: s = argv[currentObjIndex].toString();
084: len = s.length();
085: i = 0;
086: while (i < len) {
087: c = s.charAt(i);
088:
089: if ((c == '[') && doCmds) {
090: ParseResult res;
091: try {
092: interp.evalFlags = Parser.TCL_BRACKET_TERM;
093: interp.eval(s.substring(i + 1, len));
094: TclObject interp_result = interp.getResult();
095: interp_result.preserve();
096: res = new ParseResult(interp_result, i
097: + interp.termOffset);
098: } catch (TclException e) {
099: i = e.errIndex + 1;
100: throw e;
101: }
102: i = res.nextIndex + 2;
103: result.append(res.value.toString());
104: res.release();
105:
106: } else if ((c == '$') && doVars) {
107: ParseResult vres = Parser.parseVar(interp, s.substring(
108: i, len));
109: i += vres.nextIndex;
110: result.append(vres.value.toString());
111: vres.release();
112: } else if ((c == '\\') && doBackslashes) {
113: BackSlashResult bs = Interp.backslash(s, i, len);
114: i = bs.nextIndex;
115: if (bs.isWordSep) {
116: break;
117: } else {
118: result.append(bs.c);
119: }
120: } else {
121: result.append(c);
122: i++;
123: }
124: }
125:
126: interp.setResult(result.toString());
127: }
128: }
|