public static T SearchScope <T>(this Scope scope, bool preferDirectParent = false) where T : Scope { if (scope == null) { throw new ArgumentNullException("scope"); } T sought = scope as T; if (sought != null) { return(sought); } BindScope bindScope = scope as BindScope; if (bindScope != null) { sought = SearchScope <T>(preferDirectParent ? bindScope.Parent : bindScope.GrandChild); if (sought != null) { return(sought); } return(SearchScope <T>(preferDirectParent ? bindScope.GrandChild : bindScope.Parent)); } ChildScope childScope = scope as ChildScope; if (childScope != null) { return(SearchScope <T>(childScope.Parent)); } return(null); }
/// <summary> /// Ported from T * search_scope(scope_t * ptr, bool prefer_direct_parents = false) /// </summary> public static T SearchScope <T>(this Scope scope, bool preferDirectParent = false) where T : Scope { if (scope == null) { throw new ArgumentNullException("scope"); } Logger.Current.Debug("scope.search", () => String.Format("Searching scope {0}", scope.Description)); T sought = scope as T; if (sought != null) { return(sought); } BindScope bindScope = scope as BindScope; if (bindScope != null) { sought = SearchScope <T>(preferDirectParent ? bindScope.Parent : bindScope.GrandChild); if (sought != null) { return(sought); } return(SearchScope <T>(preferDirectParent ? bindScope.GrandChild : bindScope.Parent)); } ChildScope childScope = scope as ChildScope; if (childScope != null) { return(SearchScope <T>(childScope.Parent)); } return(null); }
public void ExecuteCommand(IEnumerable <string> args, bool atRepl) { Session.FlushOnNextDataFile = true; // Process the command verb, arguments and options if (atRepl) { args = ReadCommandArguments(Report, args); if (!args.Any()) { return; } } string verb = args.First(); args = args.Skip(1); // DM - skip the first item that is equal to verb = *arg++; // Look for a precommand first, which is defined as any defined function // whose name starts with "ledger_precmd_". The difference between a // precommand and a regular command is that precommands ignore the journal // data file completely, nor is the user's init file read. // // Here are some examples of pre-commands: // // parse STRING ; show how a value expression is parsed // eval STRING ; simply evaluate a value expression // format STRING ; show how a format string is parsed // // If such a command is found, create the output stream for the result and // then invoke the command. ExprFunc command; bool isPrecommand = false; BindScope boundScope = new BindScope(this, Report); command = LookForPrecommand(boundScope, verb); if (!command.IsNullOrEmpty()) { isPrecommand = true; } // If it is not a pre-command, then parse the user's ledger data at this // time if not done already (i.e., if not at a REPL). Then patch up the // report options based on the command verb. if (!isPrecommand) { if (!atRepl) { Session.ReadJournalFiles(); } Report.NormalizeOptions(verb); command = LookForCommand(boundScope, verb); if (command.IsNullOrEmpty()) { throw new LogicError(String.Format(LogicError.ErrorMessageUnrecognizedCommand, verb)); } } // Create the output stream (it might be a file, the console or a PAGER // subprocess) and invoke the report command. The output stream is closed // by the caller of this function. Report.OutputStream = FileSystem.OutputStreamInitialize( Report.OutputHandler.Handled ? Report.OutputHandler.Str() : String.Empty, Report.PagerHandler.Handled ? Report.PagerHandler.Str() : String.Empty); // Now that the output stream is initialized, report the options that will // participate in this report, if the user specified --options if (OptionsHandler.Handled) { Report.OutputStream.Write(ReportOptions(Report)); } // Create an argument scope containing the report command's arguments, and // then invoke the command. The bound scope causes lookups to happen // first in the global scope, and then in the report scope. CallScope commandArgs = new CallScope(boundScope); foreach (string arg in args) { commandArgs.PushBack(Value.Get(arg)); } var info = Logger.Current.InfoContext(TimerName.Command)?.Message("Finished executing command").Start(); // INFO_START command(commandArgs); info?.Finish(); // INFO_FINISH }