/* * SwitchCmd.java * * Copyright (c) 1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * * RCS: @(#) $Id: SwitchCmd.java,v 1.1.1.1 1998/10/14 21:09:20 cvsadmin Exp $ * */ package tcl.lang; /* * This class implements the built-in "switch" command in Tcl. */ class SwitchCmd implements Command { static final private String validCmds[] = { "-exact", "-glob", "-regexp", "--" }; private static final int EXACT = 0; private static final int GLOB = 1; private static final int REGEXP = 2; private static final int LAST = 3; /* *----------------------------------------------------------------------------- * * cmdProc -- * * This procedure is invoked to process the "switch" Tcl statement. * See the user documentation for details on what it does. * * Results: * None. * * Side effects: * See the user documentation. * *----------------------------------------------------------------------------- */ public void cmdProc( Interp interp, // Current interpreter. TclObject argv[]) // Arguments to "switch" statement. throws TclException { int i, code, mode, body; boolean matched; String string; TclObject switchArgv[] = null; mode = EXACT; for (i = 1; i < argv.length; i++) { if (!argv[i].toString().startsWith("-")) { break; } int opt = TclIndex.get(interp, argv[i], validCmds, "option", 1); if (opt == LAST) { i++; break; } else if (opt > LAST) { throw new TclException(interp, "SwitchCmd.cmdProc: bad option " + opt + " index to validCmds"); } else { mode = opt; } } if (argv.length - i < 2) { throw new TclNumArgsException(interp, 1, argv, "?switches? string pattern body ... ?default body?"); } string = argv[i].toString(); i++; /* * If all of the pattern/command pairs are lumped into a single * argument, split them out again. */ if (argv.length - i == 1) { switchArgv = TclList.getElements(interp, argv[i]); i = 0; } else { switchArgv = argv; } for (; i < switchArgv.length; i += 2) { if (i == (switchArgv.length-1)) { throw new TclException(interp, "extra switch pattern with no body"); } /* * See if the pattern matches the string. */ matched = false; String pattern = switchArgv[i].toString(); if ((i == switchArgv.length-2) && pattern.equals("default")) { matched = true; } else { switch (mode) { case EXACT: matched = string.equals(pattern); break; case GLOB: matched = Util.stringMatch(string, pattern); break; case REGEXP: matched = Util.regExpMatch(interp, string, switchArgv[i]); break; } } if (!matched) { continue; } /* * We've got a match. Find a body to execute, skipping bodies * that are "-". */ for (body = i+1; ; body += 2) { if (body >= switchArgv.length) { throw new TclException(interp, "no body specified for pattern \"" + switchArgv[i] + "\""); } if (!switchArgv[body].toString().equals("-")) { break; } } try { interp.eval(switchArgv[body], 0); return; } catch (TclException e) { if (e.getCompletionCode() == TCL.ERROR) { interp.addErrorInfo( "\n (\"" + switchArgv[i] + "\" arm line " + interp.errorLine + ")"); } throw e; } } /* * Nothing matched: return nothing. */ } } // end SwitchCmd