diff --git a/SourceGen/AppSettings.cs b/SourceGen/AppSettings.cs
index 8d06140..4f5b442 100644
--- a/SourceGen/AppSettings.cs
+++ b/SourceGen/AppSettings.cs
@@ -42,6 +42,7 @@ namespace SourceGen {
public const string MAIN_RIGHT_PANEL_WIDTH = "main-right-panel-width";
public const string MAIN_REFERENCES_HEIGHT = "main-references-height";
public const string MAIN_SYMBOLS_HEIGHT = "main-symbols-height";
+ public const string MAIN_HIDE_MESSAGE_WINDOW = "main-hide-message-window";
// New project dialog.
public const string NEWP_SELECTED_SYSTEM = "newp-selected-system";
diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs
index f72e2c0..cd4b624 100644
--- a/SourceGen/MainController.cs
+++ b/SourceGen/MainController.cs
@@ -933,7 +933,7 @@ namespace SourceGen {
mReanalysisTimer.EndTask("Call DisasmProject.Analyze()");
mReanalysisTimer.StartTask("Update message list");
- UpdateMessageList();
+ mMainWin.UpdateMessageList(mProject.Messages, mOutputFormatter);
mReanalysisTimer.EndTask("Update message list");
}
@@ -942,14 +942,6 @@ namespace SourceGen {
mReanalysisTimer.EndTask("Generate DisplayList");
}
- private void UpdateMessageList() {
- List items = new List();
- foreach (MessageList.MessageEntry entry in mProject.Messages) {
- items.Add(MessageList.FormatMessage(entry, mOutputFormatter));
- }
- mMainWin.UpdateMessageList(items);
- }
-
#endregion Project management
#region Main window UI event handlers
diff --git a/SourceGen/MessageList.cs b/SourceGen/MessageList.cs
index 4364167..07b190f 100644
--- a/SourceGen/MessageList.cs
+++ b/SourceGen/MessageList.cs
@@ -88,7 +88,8 @@ namespace SourceGen {
///
/// List of messages. This is not kept in sorted order, because the DataGrid used to
- /// display it will do the sorting for us.
+ /// display it will do the sorting for us. Call the Sort() function to establish an
+ /// initial sort.
///
private List mList;
@@ -123,6 +124,18 @@ namespace SourceGen {
mList.Clear();
}
+ ///
+ /// Sorts the list, by severity then offset.
+ ///
+ public void Sort() {
+ mList.Sort(delegate (MessageEntry a, MessageEntry b) {
+ if (a.Severity != b.Severity) {
+ return (int)b.Severity - (int)a.Severity;
+ }
+ return a.Offset - b.Offset;
+ });
+ }
+
///
/// Formats a message for display.
///
@@ -168,7 +181,8 @@ namespace SourceGen {
break;
}
- return new MainWindow.MessageListItem(severity, offset, problem, context, resolution);
+ return new MainWindow.MessageListItem(severity, entry.Offset, offset, problem,
+ context, resolution);
}
public void DebugDump() {
diff --git a/SourceGen/RuntimeData/Help/index.html b/SourceGen/RuntimeData/Help/index.html
index d97aaa1..ee277b9 100644
--- a/SourceGen/RuntimeData/Help/index.html
+++ b/SourceGen/RuntimeData/Help/index.html
@@ -56,6 +56,7 @@ and 65816 code. The official web site is
Notes Window
Symbols Window
Info Window
+ Messages Window
Navigation
Adding and Removing Hints
Format Address Table
diff --git a/SourceGen/RuntimeData/Help/mainwin.html b/SourceGen/RuntimeData/Help/mainwin.html
index 5ee8269..adb8276 100644
--- a/SourceGen/RuntimeData/Help/mainwin.html
+++ b/SourceGen/RuntimeData/Help/mainwin.html
@@ -321,6 +321,37 @@ brief description of what the instruction does. The latter can be
especially handy for undocumented instructions.
+
+
+Sometimes a change will invalidate an earlier change. For example,
+suppose you hint an area as data, and format it as a string.
+Later on you hint it as code. You now have a block of code with a
+string format record sitting in the middle of it. SourceGen tries very
+hard not to throw away anything you've done, but it will ignore anything
+invalid.
+If a problem like this is encountered, an entry is added to a list
+of messages displayed at the bottom of the window. Each entry identifies
+the nature of the problem, the severity of the problem, the offset where
+it occurred, and what was done to resolve it. The problem categories
+include:
+
+ - Hidden label: a label placed on code or data is now stuck in the
+ middle of a multi-byte instruction or data item.
+ - Unresolved weak ref: a reference to a non-existent symbol was found.
+ - Invalid offset or length: the offset or length in a format object
+ had an invalid value.
+ - Invalid descriptor: the format is inappropriate, e.g. formatting
+ an instruction as a string.
+
+The "context" column will provide additional detail about the problem.
+In most cases, the offending item will be ignored.
+Double-clicking on an entry will jump to that offset.
+The message list will not appear if there are no messages. You can
+hide the list by clicking on the "Hide" button to the left of the messages.
+Un-hide the list by clicking on the "N messages" button at the bottom-right
+corner of the application window.
+
+
The simplest way to move through the code list is with the scroll wheel
diff --git a/SourceGen/WpfGui/EditProjectProperties.xaml.cs b/SourceGen/WpfGui/EditProjectProperties.xaml.cs
index ac1f5a7..e906464 100644
--- a/SourceGen/WpfGui/EditProjectProperties.xaml.cs
+++ b/SourceGen/WpfGui/EditProjectProperties.xaml.cs
@@ -466,6 +466,12 @@ namespace SourceGen.WpfGui {
typeStr = Res.Strings.ABBREV_CONSTANT;
} else {
typeStr = Res.Strings.ABBREV_ADDRESS;
+
+ if (defSym.Direction == DefSymbol.DirectionFlags.Read) {
+ typeStr += "<";
+ } else if (defSym.Direction == DefSymbol.DirectionFlags.Write) {
+ typeStr += ">";
+ }
}
FormattedSymbol fsym = new FormattedSymbol(
diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml
index 1d9a9ef..d14ad59 100644
--- a/SourceGen/WpfGui/MainWindow.xaml
+++ b/SourceGen/WpfGui/MainWindow.xaml
@@ -42,6 +42,12 @@ limitations under the License.
+
+ {0} message
+ {0} message ({1} warning/error)
+ {0} messages
+ {0} messages ({1} warning/error)
+
diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs
index 0435328..aa2c393 100644
--- a/SourceGen/WpfGui/MainWindow.xaml.cs
+++ b/SourceGen/WpfGui/MainWindow.xaml.cs
@@ -1704,9 +1704,12 @@ namespace SourceGen.WpfGui {
public string Context { get; private set; }
public string Resolution { get; private set; }
- public MessageListItem(string severity, string offset, string type, string context,
- string resolution) {
+ public int OffsetValue { get; private set; }
+
+ public MessageListItem(string severity, int offsetValue, string offset, string type,
+ string context, string resolution) {
Severity = severity;
+ OffsetValue = offsetValue;
Offset = offset;
Type = type;
Context = context;
@@ -1714,28 +1717,93 @@ namespace SourceGen.WpfGui {
}
}
+ public Visibility MessageListVisibility {
+ get {
+ bool visible = !HideMessageList && FormattedMessages.Count > 0;
+ return visible ? Visibility.Visible : Visibility.Collapsed;
+ }
+ }
+
+ private bool HideMessageList {
+ get { return AppSettings.Global.GetBool(AppSettings.MAIN_HIDE_MESSAGE_WINDOW, false); }
+ set {
+ AppSettings.Global.SetBool(AppSettings.MAIN_HIDE_MESSAGE_WINDOW, value);
+ OnPropertyChanged("MessageListVisibility");
+ }
+ }
+
+ private string mMessageStatusText;
+ public string MessageStatusText {
+ get { return mMessageStatusText; }
+ set { mMessageStatusText = value; OnPropertyChanged(); }
+ }
+
///
/// ItemsSource for DataGrid.
///
public ObservableCollection FormattedMessages { get; private set; } =
new ObservableCollection();
- public void UpdateMessageList(List list) {
+ private void MessageStatusButton_Click(object sender, RoutedEventArgs e) {
+ HideMessageList = false;
+ }
+
+ private void HideMessageList_Click(object sender, RoutedEventArgs e) {
+ HideMessageList = true;
+ }
+
+ private void MessageGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
+ if (!messageGrid.GetClickRowColItem(e, out int unusedRow, out int unusedCol,
+ out object item)) {
+ // Header or empty area; ignore.
+ return;
+ }
+ MessageListItem mli = (MessageListItem)item;
+
+ // Jump to the offset, then shift the focus back to the code list.
+ mMainCtrl.GoToLocation(new NavStack.Location(mli.OffsetValue, 0, false),
+ MainController.GoToMode.JumpToCodeData, true);
+ codeListView.Focus();
+ }
+
+ ///
+ /// Regenerates the contents of the message list.
+ ///
+ /// Message list.
+ /// Format object.
+ public void UpdateMessageList(MessageList list, Asm65.Formatter formatter) {
FormattedMessages.Clear();
- foreach (MessageListItem item in list) {
- FormattedMessages.Add(item);
+ list.Sort();
+
+ int warnErrCount = 0;
+ foreach (MessageList.MessageEntry entry in list) {
+ FormattedMessages.Add(MessageList.FormatMessage(entry, formatter));
+ if (entry.Severity != MessageList.MessageEntry.SeverityLevel.Info) {
+ warnErrCount++;
+ }
+ }
+
+ if (warnErrCount == 0) {
+ if (FormattedMessages.Count == 1) {
+ string fmt = (string)FindResource("str_MessageSingularFmt");
+ MessageStatusText = string.Format(fmt, FormattedMessages.Count);
+ } else {
+ string fmt = (string)FindResource("str_MessagePluralFmt");
+ MessageStatusText = string.Format(fmt, FormattedMessages.Count);
+ }
+ } else {
+ if (FormattedMessages.Count == 1) {
+ string fmt = (string)FindResource("str_MessageSingularWarningFmt");
+ MessageStatusText = string.Format(fmt, FormattedMessages.Count, warnErrCount);
+ } else {
+ string fmt = (string)FindResource("str_MessagePluralWarningFmt");
+ MessageStatusText = string.Format(fmt, FormattedMessages.Count, warnErrCount);
+ }
}
OnPropertyChanged("MessageListVisibility");
}
- public Visibility MessageListVisibility {
- get {
- bool visible = FormattedMessages.Count > 0;
- return visible ? Visibility.Visible : Visibility.Collapsed;
- }
- }
-
#endregion Message list panel
}
}