Example #1
0
        ///////////////////////////////////////////////////////////////////////

        #region Callback Methods
        private ReturnCode InterruptCallback(
            Interpreter interpreter, /* NOTE: Parent interpreter. */
            InterruptType interruptType,
            IClientData clientData,
            ref Result error
            ) /* throw */
        {
            //
            // NOTE: If the are no callback arguments configured, just skip it
            //       and return success.
            //
            StringList arguments = CallbackArguments;

            if (arguments == null) /* NOTE: Disabled? */
            {
                return(ReturnCode.Ok);
            }

            Interpreter debugInterpreter = this.interpreter;

            if (debugInterpreter == null)
            {
                error = "debugger interpreter not available";
                return(ReturnCode.Error);
            }

            //
            // NOTE: *WARNING* This is a cross-interpreter call, do NOT dispose
            //       the parent interpreter because we do not own it.  This is
            //       guaranteed by using the NoDispose object flag (indirectly)
            //       here.
            //
            ICallback callback = CommandCallback.Create(
                MarshalFlags.Default, CallbackFlags.Default,
                ObjectFlags.Callback, ByRefArgumentFlags.None,
                debugInterpreter, clientData, null, new StringList(
                    arguments), ref error);

            if (callback == null)
            {
                return(ReturnCode.Error);
            }

            try
            {
                callback.FireEventHandler(this,
                                          RuntimeOps.GetInterruptEventArgs(interpreter,
                                                                           interruptType, clientData) as EventArgs);

                return(ReturnCode.Ok);
            }
            catch (Exception e)
            {
                error = e;
            }

            return(ReturnCode.Error);
        }
Example #2
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            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)
                        {
                            //
                            // NOTE: Programmatically interact with the debugger (breakpoint, watch,
                            //       eval, etc).
                            //
                            switch (subCommand)
                            {
                            case "clear":
                            {
                                if (arguments.Count == 2)
                                {
                                    code = interpreter.ClearCallbackQueue(ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback clear\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "count":
                            {
                                if (arguments.Count == 2)
                                {
                                    int count = 0;

                                    code = interpreter.CountCallbacks(ref count, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = count;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback count\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "dequeue":
                            {
                                if (arguments.Count >= 2)
                                {
                                    OptionDictionary options = ObjectOps.GetDequeueOptions();

                                    int argumentIndex = Index.Invalid;

                                    if (arguments.Count > 2)
                                    {
                                        code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);
                                    }
                                    else
                                    {
                                        code = ReturnCode.Ok;
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        if (argumentIndex == Index.Invalid)
                                        {
                                            Type        returnType;
                                            ObjectFlags objectFlags;
                                            string      objectName;
                                            string      interpName;
                                            bool        create;
                                            bool        dispose;
                                            bool        alias;
                                            bool        aliasRaw;
                                            bool        aliasAll;
                                            bool        aliasReference;
                                            bool        toString;

                                            ObjectOps.ProcessFixupReturnValueOptions(
                                                options, null, out returnType, out objectFlags,
                                                out objectName, out interpName, out create,
                                                out dispose, out alias, out aliasRaw, out aliasAll,
                                                out aliasReference, out toString);

                                            //
                                            // NOTE: Which Tcl interpreter do we want a command alias created
                                            //       in, if any?
                                            //
                                            ICallback callback = null;

                                            code = interpreter.DequeueCallback(ref callback, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                ObjectOptionType objectOptionType = ObjectOptionType.Dequeue |
                                                                                    ObjectOps.GetOptionType(aliasRaw, aliasAll);

                                                code = MarshalOps.FixupReturnValue(
                                                    interpreter, interpreter.Binder, interpreter.CultureInfo,
                                                    returnType, objectFlags, ObjectOps.GetInvokeOptions(
                                                        objectOptionType), objectOptionType, objectName, interpName,
                                                    callback, create, dispose, alias, aliasReference, toString,
                                                    ref result);
                                            }
                                        }
                                        else
                                        {
                                            result = "wrong # args: should be \"callback dequeue ?options?\"";
                                            code   = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback dequeue ?options?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "enqueue":
                            {
                                if (arguments.Count >= 3)
                                {
                                    ICallback callback = CommandCallback.Create(
                                        MarshalFlags.Default, CallbackFlags.Default,
                                        ObjectFlags.Callback, ByRefArgumentFlags.None,
                                        interpreter, clientData, null, new StringList(
                                            arguments, 2), ref result);

                                    if (callback != null)
                                    {
                                        code = interpreter.EnqueueCallback(callback, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = String.Empty;
                                        }
                                    }
                                    else
                                    {
                                        code = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback enqueue name ?arg ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "execute":
                            {
                                if (arguments.Count == 2)
                                {
                                    code = interpreter.ExecuteCallbackQueue(ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback execute\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "list":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    StringList list = null;

                                    code = interpreter.ListCallbacks(
                                        pattern, false, ref list, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = list;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback list ?pattern?\"";
                                    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 \"callback option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Example #3
0
        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)
                    {
                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null, OptionFlags.None, 1, Index.Invalid, "-ascii", null),
                            new Option(null, OptionFlags.None, 1, Index.Invalid, "-dictionary", null),
                            new Option(null, OptionFlags.None, 1, Index.Invalid, "-integer", null),
                            new Option(null, OptionFlags.None, 1, Index.Invalid, "-random", null),
                            new Option(null, OptionFlags.None, 1, Index.Invalid, "-real", null),
                            new Option(null, OptionFlags.None, 2, Index.Invalid, "-increasing", null),
                            new Option(null, OptionFlags.None, 2, Index.Invalid, "-decreasing", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-unique", null),
                            new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-command", null),
                            new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-index", null) // NOTE: Of sub-lists, not list.
                        });

                        int argumentIndex = Index.Invalid;

                        code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result);

                        if (code == ReturnCode.Ok)
                        {
                            if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count))
                            {
                                StringList list = null;

                                //
                                // WARNING: Cannot cache list representation here, the list
                                //          is modified below.
                                //
                                code = Parser.SplitList(
                                    interpreter, arguments[argumentIndex], 0,
                                    Length.Invalid, false, ref list, ref result);

                                if (code == ReturnCode.Ok)
                                {
                                    Variant value     = null;
                                    string  indexText = null;

                                    if (options.IsPresent("-index", ref value))
                                    {
                                        indexText = value.ToString();
                                    }

                                    bool ascending = true; // FIXME: PRI 5: Default handling.

                                    if (options.IsPresent("-decreasing"))
                                    {
                                        ascending = false;
                                    }
                                    else if (options.IsPresent("-increasing"))
                                    {
                                        ascending = true;
                                    }

                                    bool noCase = false;

                                    if (options.IsPresent("-nocase"))
                                    {
                                        noCase = true;
                                    }

                                    bool unique = false;

                                    if (options.IsPresent("-unique"))
                                    {
                                        unique = true;
                                    }

                                    IntDictionary      duplicates = null;
                                    IComparer <string> comparer   = null;

                                    if (options.IsPresent("-command", ref value))
                                    {
                                        StringList callbackArguments = null;

                                        if (value.IsList())
                                        {
                                            callbackArguments = (StringList)value.Value;
                                        }
                                        else
                                        {
                                            string temporary = value.ToString();

                                            code = Parser.SplitList(
                                                interpreter, temporary, 0, Length.Invalid,
                                                true, ref callbackArguments);
                                        }

                                        if (code == ReturnCode.Ok)
                                        {
                                            ICallback callback = CommandCallback.Create(
                                                MarshalFlags.Default, CallbackFlags.Default,
                                                ObjectFlags.Callback, ByRefArgumentFlags.None,
                                                interpreter, _Public.ClientData.Empty, null,
                                                callbackArguments, ref result);

                                            if (callback != null)
                                            {
                                                comparer = new _Comparers.StringCommandComparer(
                                                    interpreter, callback, ascending, indexText, false,
                                                    unique, interpreter.CultureInfo, ref duplicates);
                                            }
                                            else
                                            {
                                                code = ReturnCode.Error;
                                            }
                                        }
                                    }
                                    else if (options.IsPresent("-dictionary"))
                                    {
                                        comparer = new _Comparers.StringDictionaryComparer(
                                            interpreter, ascending, indexText, false, unique,
                                            interpreter.CultureInfo, ref duplicates);
                                    }
                                    else if (options.IsPresent("-integer"))
                                    {
                                        comparer = new _Comparers.StringIntegerComparer(
                                            interpreter, ascending, indexText, false, unique,
                                            interpreter.CultureInfo, ref duplicates);
                                    }
                                    else if (options.IsPresent("-random"))
                                    {
                                        comparer = new _Comparers.StringRandomComparer(
                                            interpreter, ascending, indexText, false, unique,
                                            interpreter.CultureInfo, interpreter.RandomNumberGenerator,
                                            ref duplicates);
                                    }
                                    else if (options.IsPresent("-real"))
                                    {
                                        comparer = new _Comparers.StringRealComparer(
                                            interpreter, ascending, indexText, false, unique,
                                            interpreter.CultureInfo, ref duplicates);
                                    }
                                    else if (options.IsPresent("-ascii") || true) // FIXME: PRI 5: Default handling.
                                    {
                                        comparer = new _Comparers.StringAsciiComparer(
                                            interpreter, ascending, indexText, false, noCase,
                                            unique, interpreter.CultureInfo, ref duplicates);
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        try
                                        {
                                            lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                            {
                                                if (comparer != null)
                                                {
                                                    list.Sort(comparer);
                                                }
                                                else
                                                {
                                                    //
                                                    // FIXME: This will never be hit because we always default
                                                    //        to using the StringAsciiComparer (above).
                                                    //
                                                    list.Sort(); // use .NET Framework defaults
                                                }
                                            }

                                            //
                                            // NOTE: If we are in unique mode, remove any duplicates from
                                            //       the final resulting list now.
                                            //
                                            if (unique)
                                            {
                                                StringList uniqueList = new StringList();

                                                //
                                                // NOTE: Process each element in the list to see if it has
                                                //       been counted as a duplicate value by the comparer.
                                                //
                                                //       If the value has not been added to the final resulting
                                                //       list yet, add it now and mark the value so that it will
                                                //       never be added again (i.e. we only want the first value
                                                //       from every group of duplicates and we want all the other
                                                //       values as well).
                                                //
                                                // HACK: In the worst possible case, this loop can have a runtime
                                                //       of O(N^2), including called functions, primarily due to
                                                //       the inability of .NET to provide proper context to
                                                //       IComparer callbacks.  This code could be avoided entirely
                                                //       if there was an interface for sorting comparison callbacks
                                                //       that provided the indexes of the elements being compared
                                                //       in addition to their values.
                                                //
                                                foreach (string element in list) /* O(N) */
                                                {
                                                    //
                                                    // NOTE: Has this value been marked as having been previously
                                                    //       added to the final resulting list?
                                                    //
                                                    int count =
                                                        ListOps.GetDuplicateCount(comparer, duplicates, element);

                                                    if (count != Count.Invalid)
                                                    {
                                                        //
                                                        // NOTE: Add this element into the final resulting list.
                                                        //       Either it has no duplicates or we have not yet
                                                        //       added it to the final resulting list.
                                                        //
                                                        uniqueList.Add(element);

                                                        //
                                                        // NOTE: If this value had any duplicates, mark the value
                                                        //       as having been added to the final resulting list.
                                                        //
                                                        if (!ListOps.SetDuplicateCount(comparer, duplicates, element, Count.Invalid))
                                                        {
                                                            result = String.Format(
                                                                "failed to update duplicate count for element \"{0}\"",
                                                                element);

                                                            code = ReturnCode.Error;
                                                            break;
                                                        }
                                                    }
                                                }

                                                //
                                                // NOTE: The list of unique elements is now the result.
                                                //
                                                if (code == ReturnCode.Ok)
                                                {
                                                    list = uniqueList;
                                                }
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                result = list;
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            Engine.SetExceptionErrorCode(interpreter, e);

                                            if (e.InnerException != null)
                                            {
                                                result = e.InnerException.Message;
                                            }
                                            else if (e is ScriptException)
                                            {
                                                result = e.Message;
                                            }
                                            else
                                            {
                                                result = e;
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if ((argumentIndex != Index.Invalid) &&
                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                {
                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"lsort ?options? list\"";
                                }

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"lsort ?options? list\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Example #4
0
        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode UploadDataAsync(
            Interpreter interpreter,
            IClientData clientData,
            StringList arguments,
            CallbackFlags callbackFlags,
            Uri uri,
            string method,
            byte[] rawData,
            ref Result error
            )
        {
            TraceOps.DebugTrace(String.Format(
                                    "UploadDataAsync: interpreter = {0}, clientData = {1}, " +
                                    "arguments = {2}, callbackFlags = {3}, uri = {4}, " +
                                    "method = {5}, rawData = {6}",
                                    FormatOps.InterpreterNoThrow(interpreter),
                                    FormatOps.WrapOrNull(clientData),
                                    FormatOps.WrapOrNull(true, true, arguments),
                                    FormatOps.WrapOrNull(callbackFlags),
                                    FormatOps.WrapOrNull(uri),
                                    FormatOps.WrapOrNull(method),
                                    FormatOps.WrapOrNull(rawData)),
                                typeof(WebOps).Name, TracePriority.NetworkDebug);

            ReturnCode code      = ReturnCode.Ok;
            WebClient  webClient = null;

            try
            {
                ICallback callback = CommandCallback.Create(
                    MarshalFlags.Default, callbackFlags,
                    ObjectFlags.Callback, ByRefArgumentFlags.None,
                    interpreter, null, null, arguments, ref error);

                if (callback != null)
                {
                    try
                    {
                        Result localError = null;

                        webClient = CreateClient(
                            interpreter, "UploadDataAsync", clientData,
                            ref localError);

                        if (webClient != null)
                        {
                            callback.ClientData = new ClientData(
                                new AnyTriplet <WebClient, Uri,
                                                IAnyPair <string, byte[]> >(
                                    webClient, uri, new AnyPair <string,
                                                                 byte[]>(method, rawData)));

                            webClient.UploadDataCompleted +=
                                new UploadDataCompletedEventHandler(
                                    UploadDataAsyncCompleted);

                            /* NO RESULT */
                            webClient.UploadDataAsync(
                                uri, method, rawData, callback);
                        }
                        else if (localError != null)
                        {
                            error = localError;
                            code  = ReturnCode.Error;
                        }
                        else
                        {
                            error = "could not create web client";
                            code  = ReturnCode.Error;
                        }
                    }
                    catch (Exception e)
                    {
                        error = e;
                        code  = ReturnCode.Error;
                    }
                }
                else
                {
                    code = ReturnCode.Error;
                }
            }
            finally
            {
                if ((code != ReturnCode.Ok) && (webClient != null))
                {
                    ReturnCode disposeCode;
                    Result     disposeError = null;

                    disposeCode = ObjectOps.TryDispose(
                        webClient, ref disposeError);

                    if (disposeCode != ReturnCode.Ok)
                    {
                        DebugOps.Complain(
                            interpreter, disposeCode, disposeError);
                    }
                }
            }

            return(code);
        }