Module: environment-application-commands Synopsis: The application commands provided by the environment Author: Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define class () slot context-stack-frame :: false-or() = #f; slot context-bug-report :: false-or() = #f; slot context-thread :: false-or() = #f; slot context-show-messages? :: = #f; slot context-last-transaction-id = #f; slot context-interactive-warnings :: = #[]; slot context-start-command :: false-or() = #f; slot context-debug-request? :: = #f; end class ; define method context-application-context (context :: ) => (context :: ) let project-context = context.context-project-context; let properties = project-context.context-properties; get-property(properties, #"application", default: #f) | begin let application-context :: = make(); project-context.context-properties := put-property!(properties, #"application", application-context); application-context end end method context-application-context; define method context-application-tethered? (context :: ) => (tethered? :: ) let project-context = context.context-project-context; let project = project-context & project-context.context-project; project & project.application-tethered? end method context-application-tethered?; /// Application command library define constant $interactive-command-prompt = "? "; define class () end class ; define constant $application-command-library = make(); register-default-command-library($application-command-library); define method command-library-prompt (context :: , library :: ) => (prompt :: false-or()) if (context.context-application-tethered?) $interactive-command-prompt end end method command-library-prompt; define method command-library-default-command-class (context :: , library :: ) => (class :: false-or(subclass())) if (context.context-application-tethered?) end end method command-library-default-command-class; /// Useful command classes define abstract class () end class ; define abstract class () end class ; define abstract class () end class ; define method ensure-command-available (context :: , command :: ) => () unless (context.context-application-tethered?) command-error("Application command '%s' requires an open application", command-title(context, command)) end end method ensure-command-available; define method ensure-property-available (context :: , property :: ) => () unless (context.context-application-tethered?) command-error("Application property '%s' requires an open application", property.command-info-title) end end method ensure-property-available; /// Thread argument parsing define sideways method parameter-type-name (type == ) => (name :: ) "thread" end method parameter-type-name; define sideways method parse-next-argument (context :: , type == , text :: , #key start :: = 0, end: stop = #f) => (value :: , next-index :: ) let (index, next-index) = string-to-integer(text, start: start, end: stop); if (index) block (return) let project = context.context-project; let thread = project & find-indexed-thread(project, index); if (thread) values(thread, next-index) else parse-error("No thread %d", index) end end else parse-error("Missing thread argument") end end method parse-next-argument; define method find-indexed-thread (project :: , index :: ) => (thread :: false-or()) let application = project.project-application; if (application) block (return) for (thread :: in application.application-threads) let thread-index = thread-index(application, thread); if (index == thread-index) return(thread) end end; #f end end end method find-indexed-thread; /// Restart argument parsing define sideways method parameter-type-name (type == ) => (name :: ) "restart" end method parameter-type-name; define sideways method parse-next-argument (context :: , type == , text :: , #key start :: = 0, end: stop = #f) => (value :: , next-index :: ) let (index, next-index) = string-to-integer(text, start: start, end: stop); if (index) block (return) let project = context.context-project; let application-context = project & context.context-application-context; let thread = application-context & application-context.context-thread; let restart = thread & find-indexed-restart(project, thread, index); if (restart) values(restart, next-index) else parse-error("No restart %d", index) end end else parse-error("Missing restart argument") end end method parse-next-argument; define method find-indexed-restart (project :: , thread :: , index :: ) => (restart :: false-or()) let application = project.project-application; if (application) index := index - 1; // restarts are one indexed let restarts = application-thread-restarts(project, thread); if (index >= 0 & index < restarts.size) restarts[index] end end end method find-indexed-restart; /// Stack frame argument parsing define sideways method parameter-type-name (type == ) => (name :: ) "frame" end method parameter-type-name; define sideways method parse-next-argument (context :: , type == , text :: , #key start :: = 0, end: stop = #f) => (value :: , next-index :: ) let (index, next-index) = string-to-integer(text, start: start, end: stop); if (index) block (return) let project = context.context-project; let thread = if (project) let application-context = context.context-application-context; application-context.context-thread end; let stack-frame = thread & find-indexed-stack-frame(project, thread, index - 1); if (stack-frame) values(stack-frame, next-index) else parse-error("No stack-frame %d", index) end end else parse-error("Missing stack frame argument") end end method parse-next-argument; define method stack-frame-index (project :: , thread :: , frame :: ) => (index :: false-or()) let application = project.project-application; if (application) let stack = thread-complete-stack-trace(project, thread); position(stack, frame) end end method stack-frame-index; define method find-indexed-stack-frame (project :: , thread :: , index :: ) => (frame :: false-or()) let application = project.project-application; if (application) let stack = thread-complete-stack-trace(project, thread); if (index >= 0 & index < stack.size) stack[index] end end end method find-indexed-stack-frame; /// Remote machine argument parsing define sideways method parameter-type-name (type == ) => (name :: ) "machine" end method parameter-type-name; define sideways method parse-next-argument (context :: , type == , text :: , #key start :: = 0, end: stop = #f) => (value :: , next-index :: ) let (address, next-index) = parse-next-word(text, start: start, end: stop); if (address) let project = context.context-project; let machine = find-remote-connection(context, address); if (machine) values(machine, next-index) else parse-error("No machine named '%s'", address) end else parse-error("Missing machine argument") end end method parse-next-argument;