using Mesen.GUI.Config; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace Mesen.GUI.Debugger { class WatchManager { public static event EventHandler WatchChanged; private static List _watchEntries = new List(); private static Regex _arrayWatchRegex = new Regex(@"\[((\$[0-9A-Fa-f]+)|(\d+)|([@_a-zA-Z0-9]+))\s*,\s*(\d+)\]", RegexOptions.Compiled); public static Regex FormatSuffixRegex = new Regex(@"^(.*),\s*([B|H|S|U])([\d]){0,1}$", RegexOptions.Compiled); public static List WatchEntries { get { return _watchEntries; } set { _watchEntries = new List(value); WatchChanged?.Invoke(null, EventArgs.Empty); } } public static List GetWatchContent(List previousValues) { WatchFormatStyle defaultStyle = ConfigManager.Config.Debug.WatchFormat; int defaultByteLength = 1; if(defaultStyle == WatchFormatStyle.Signed) { defaultByteLength = 4; } var list = new List(); for(int i = 0; i < _watchEntries.Count; i++) { string expression = _watchEntries[i].Trim(); string newValue = ""; EvalResultType resultType; string exprToEvaluate = expression; WatchFormatStyle style = defaultStyle; int byteLength = defaultByteLength; if(expression.StartsWith("{") && expression.EndsWith("}")) { //Default to 2-byte values when using {} syntax byteLength = 2; } ProcessFormatSpecifier(ref exprToEvaluate, ref style, ref byteLength); bool forceHasChanged = false; Match match = _arrayWatchRegex.Match(expression); if(match.Success) { //Watch expression matches the array display syntax (e.g: [$300,10] = display 10 bytes starting from $300) newValue = ProcessArrayDisplaySyntax(style, ref forceHasChanged, match); } else { Int32 result = DebugApi.EvaluateExpression(exprToEvaluate, out resultType, true); switch(resultType) { case EvalResultType.Numeric: newValue = FormatValue(result, style, byteLength); break; case EvalResultType.Boolean: newValue = result == 0 ? "false" : "true"; break; case EvalResultType.Invalid: newValue = ""; forceHasChanged = true; break; case EvalResultType.DivideBy0: newValue = ""; forceHasChanged = true; break; case EvalResultType.OutOfScope: newValue = "