/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { if (code == ReturnCode.Ok) { switch (subCommand) { case "command": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool nested = false; if (options.IsPresent("-nested", ref value)) { nested = (bool)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); code = Parser.ParseCommand( interpreter, arguments[argumentIndex], startIndex, characters, nested, state, noReady, ref result); if (code == ReturnCode.Ok) { // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse command ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse command ?options? text\""; code = ReturnCode.Error; } break; } case "expression": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); code = ExpressionParser.ParseExpression( interpreter, arguments[argumentIndex], startIndex, characters, state, noReady, ref result); if (code == ReturnCode.Ok) { // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse expression ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse expression ?options? text\""; code = ReturnCode.Error; } break; } case "options": { if (arguments.Count >= 4) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(OptionBehaviorFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-flags", new Variant(OptionBehaviorFlags.Default)), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-optionsvar", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-indexes", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-allowinteger", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-strict", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-verbose", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-novalue", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noset", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-simple", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count)) { Variant value = null; string optionsVarName = Vars.OptionSet.Options; if (options.IsPresent("-optionsvar", ref value)) { optionsVarName = value.ToString(); } OptionBehaviorFlags flags = OptionBehaviorFlags.Default; if (options.IsPresent("-flags", ref value)) { flags = (OptionBehaviorFlags)value.Value; } bool indexes = false; if (options.IsPresent("-indexes")) { indexes = true; } bool allowInteger = false; if (options.IsPresent("-allowinteger")) { allowInteger = true; } bool strict = false; if (options.IsPresent("-strict")) { strict = true; } bool verbose = false; if (options.IsPresent("-verbose")) { verbose = true; } bool noCase = false; if (options.IsPresent("-nocase")) { noCase = true; } bool noValue = false; if (options.IsPresent("-novalue")) { noValue = true; } bool noSet = false; if (options.IsPresent("-noset")) { noSet = true; } bool noReady = false; if (options.IsPresent("-noready")) { noReady = true; } bool simple = false; if (options.IsPresent("-simple")) { simple = true; } OptionDictionary newOptions = null; AppDomain appDomain = interpreter.GetAppDomain(); CultureInfo cultureInfo = interpreter.CultureInfo; if (simple) { newOptions = OptionDictionary.FromString( interpreter, arguments[argumentIndex], appDomain, Value.GetTypeValueFlags( allowInteger, strict, verbose, noCase), cultureInfo, ref result); } else { newOptions = OptionDictionary.FromString( interpreter, arguments[argumentIndex], appDomain, allowInteger, strict, verbose, noCase, cultureInfo, ref result); } if (newOptions != null) { StringList list = StringList.FromString( arguments[argumentIndex + 1], ref result); if (list != null) { ArgumentList newArguments = new ArgumentList(list); int nextIndex = Index.Invalid; int endIndex = Index.Invalid; code = interpreter.GetOptions( newOptions, newArguments, 0, 0, Index.Invalid, flags, noCase, noValue, noSet, ref nextIndex, ref endIndex, ref result); if (code == ReturnCode.Ok) { VariableFlags variableFlags = VariableFlags.None; if (noReady) { variableFlags |= VariableFlags.NoReady; } if (indexes) { code = interpreter.SetVariableValue2( variableFlags, optionsVarName, Vars.OptionSet.NextIndex, nextIndex.ToString(), null, ref result); if (code == ReturnCode.Ok) { code = interpreter.SetVariableValue2( variableFlags, optionsVarName, Vars.OptionSet.EndIndex, endIndex.ToString(), null, ref result); } } if (code == ReturnCode.Ok) { foreach (KeyValuePair <string, IOption> pair in newOptions) { IOption option = pair.Value; if (option == null) { continue; } if (option.IsIgnored(newOptions)) { continue; } /* REUSED */ value = null; bool present = option.IsPresent(newOptions, ref value); if (present && !option.CanBePresent(newOptions, ref result)) { code = ReturnCode.Error; break; } code = interpreter.SetVariableValue2( variableFlags, optionsVarName, pair.Key, present.ToString(), null, ref result); if (code != ReturnCode.Ok) { break; } if (option.MustHaveValue(newOptions)) { // // NOTE: If the option was not actually present, // grab and use the default value instead. // if (!present) { value = option.Value; } // // NOTE: Only set the value if the option was // actually present OR there is a bonafide // default value. // if (present || (value != null)) { string index = pair.Key + Characters.Comma + Vars.OptionSet.Value; code = interpreter.SetVariableValue2( variableFlags, optionsVarName, index, (value != null) ? value.ToString() : null, null, ref result); if (code != ReturnCode.Ok) { break; } } } } if (code == ReturnCode.Ok) { result = String.Empty; } } } } else { code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse options ?options? optionList argumentList\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse options ?options? options optionList argumentList\""; code = ReturnCode.Error; } break; } case "script": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-filename", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-currentline", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-syntax", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-strict", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-roundtrip", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } string fileName = null; if (options.IsPresent("-filename", ref value)) { fileName = value.ToString(); } int currentLine = Parser.StartLine; if (options.IsPresent("-currentline", ref value)) { currentLine = (int)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool nested = false; if (options.IsPresent("-nested", ref value)) { nested = (bool)value.Value; } bool syntax = false; if (options.IsPresent("-syntax", ref value)) { syntax = (bool)value.Value; } bool strict = false; if (options.IsPresent("-strict", ref value)) { strict = (bool)value.Value; } bool roundTrip = false; if (options.IsPresent("-roundtrip", ref value)) { roundTrip = (bool)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); TokenList tokens = null; code = Parser.ParseScript( interpreter, fileName, currentLine, arguments[argumentIndex], startIndex, characters, engineFlags, substitutionFlags, nested, noReady, syntax, strict, ref state, ref tokens, ref result); if (code == ReturnCode.Ok) { if (roundTrip) { // // NOTE: Return only the tokens that // are absolutely necessary to // rebuild the script text. // TokenList newTokens = new TokenList(); for (int index = 0; index < tokens.Count; index++) { IToken token = tokens[index]; if (token.Type == TokenType.Variable) { index += token.Components; } else if ((token.Type != TokenType.Separator) && (token.Components != 0)) { continue; } newTokens.Add(token); } result = newTokens.ToString(); } else { // // NOTE: Replace final token list // with the one we have been // building. // state.Tokens = tokens; // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse script ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse script ?options? text\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } } else { result = "wrong # args: should be \"parse type ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }