From beb10245504f6c5c69b6c498c895d01ab7155809 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Wed, 14 Aug 2019 15:25:09 -0700 Subject: [PATCH] Define and use "delimiter sets" A delimiter definition is four strings (prefix, open, close, suffix) that are concatenated with the character or string data to form an operand. A delimiter set is a collection of delimiter definitions, with separate entries for each character encoding. This is a convenient way to configure Formatter objects, import and export data from the app settings file, and manage the UI needed to allow the user to customize how things look. The full set of options didn't fit on the first app settings tab, so there's now a separate tab just for specifying character and string delimiters. (This might be overkill, but there are various plausible scenarios that make use of it.) The delimiters for on-screen display of strings can now be configured. --- Asm65/Formatter.cs | 211 +++++++++--- Asm65/StringOpFormatter.cs | 32 +- SourceGen/AppSettings.cs | 7 +- SourceGen/AsmGen/AsmAcme.cs | 8 +- SourceGen/AsmGen/AsmCc65.cs | 8 +- SourceGen/AsmGen/AsmMerlin32.cs | 8 +- SourceGen/AsmGen/AsmTass64.cs | 7 +- SourceGen/MainController.cs | 37 ++- SourceGen/PseudoOp.cs | 11 +- SourceGen/WpfGui/EditAppSettings.xaml | 393 ++++++++++++++++------- SourceGen/WpfGui/EditAppSettings.xaml.cs | 195 +++++++---- 11 files changed, 667 insertions(+), 250 deletions(-) diff --git a/Asm65/Formatter.cs b/Asm65/Formatter.cs index 3ea1e9d..5aba27f 100644 --- a/Asm65/Formatter.cs +++ b/Asm65/Formatter.cs @@ -73,11 +73,8 @@ namespace Asm65 { public string mBoxLineCommentDelimiter; // usually blank or ';' // delimiter patterns for single character constants - // (currently also used for on-screen strings; asm gen strings are handled differently) - public string mAsciiDelimPattern; - public string mHighAsciiDelimPattern; - public string mC64PetsciiDelimPattern; - public string mC64ScreenCodeDelimPattern; + public DelimiterSet mCharDelimiters; + public DelimiterSet mStringDelimiters; // miscellaneous public bool mSpacesBetweenBytes; // "20edfd" vs. "20 ed fd" @@ -104,33 +101,163 @@ namespace Asm65 { } } + #region Text Delimiters + /// - /// Container for string delimiter pieces. Instances are immutable. + /// Container for character and string delimiter pieces. Instances are immutable. /// /// - /// The prefix is included at the start of the first line, but not included on - /// subsequent lines. This is primarily intended for the on-screen display, not - /// assembly source generation. The suffix is not used at all here; this class is - /// shared with the code that generates single-character operands. + /// For single-character operands, a simple concatenation of the four fields, with the + /// character in the middle, is performed. + /// + /// For strings, the prefix is included at the start of the first line, but not included + /// on subsequent lines. This is primarily intended for the on-screen display, not + /// assembly source generation. The suffix is not used at all. /// - public class DelimiterSet { + public class DelimiterDef { public string Prefix { get; private set; } public char OpenDelim { get; private set; } public char CloseDelim { get; private set; } public string Suffix { get; private set; } - public DelimiterSet(char delim) { + public DelimiterDef(char delim) { OpenDelim = CloseDelim = delim; Prefix = Suffix = string.Empty; } - public DelimiterSet(string prefix, char openDelim, char closeDelim, string suffix) { + public DelimiterDef(string prefix, char openDelim, char closeDelim, string suffix) { + Debug.Assert(prefix != null); + Debug.Assert(suffix != null); Prefix = prefix; OpenDelim = openDelim; CloseDelim = closeDelim; Suffix = suffix; } + public override string ToString() { + return Prefix + OpenDelim + '#' + CloseDelim + Suffix; + } } - public static DelimiterSet DOUBLE_QUOTE_DELIM = new DelimiterSet('"'); + public static DelimiterDef SINGLE_QUOTE_DELIM = new DelimiterDef('\''); + public static DelimiterDef DOUBLE_QUOTE_DELIM = new DelimiterDef('"'); + + public class DelimiterSet { + private Dictionary mDelimiters = + new Dictionary(); + + /// + /// Returns the specified DelimiterDef, or a default if not found. + /// + public DelimiterDef Get(CharEncoding.Encoding enc) { + if (!mDelimiters.TryGetValue(enc, out DelimiterDef def)) { + return DOUBLE_QUOTE_DELIM; + } + return def; + } + public void Set(CharEncoding.Encoding enc, DelimiterDef def) { + mDelimiters[enc] = def; + } + public override string ToString() { + StringBuilder sb = new StringBuilder(); + foreach (KeyValuePair kvp in mDelimiters) { + sb.Append("[" + kvp.Key + ": " + kvp.Value + "]"); + } + return sb.ToString(); + } + + public static DelimiterSet GetDefaultCharDelimiters() { + DelimiterSet chrDel = new DelimiterSet(); + chrDel.Set(CharEncoding.Encoding.Ascii, + new DelimiterDef(string.Empty, '\u2018', '\u2019', string.Empty)); + chrDel.Set(CharEncoding.Encoding.HighAscii, + new DelimiterDef(string.Empty, '\u2018', '\u2019', " | $80")); + chrDel.Set(CharEncoding.Encoding.C64Petscii, + new DelimiterDef("pet:", '\u2018', '\u2019', string.Empty)); + chrDel.Set(CharEncoding.Encoding.C64ScreenCode, + new DelimiterDef("scr:", '\u2018', '\u2019', string.Empty)); + return chrDel; + } + + public static DelimiterSet GetDefaultStringDelimiters() { + DelimiterSet strDel = new DelimiterSet(); + strDel.Set(CharEncoding.Encoding.Ascii, + new DelimiterDef(string.Empty, '\u201c', '\u201d', string.Empty)); + strDel.Set(CharEncoding.Encoding.HighAscii, + new DelimiterDef("\u2191", '\u201c', '\u201d', string.Empty)); + strDel.Set(CharEncoding.Encoding.C64Petscii, + new DelimiterDef("pet:", '\u201c', '\u201d', string.Empty)); + strDel.Set(CharEncoding.Encoding.C64ScreenCode, + new DelimiterDef("scr:", '\u201c', '\u201d', string.Empty)); + return strDel; + } + + /// + /// Serializes a DelimiterSet. + /// + /// + /// Can't use Javascript from a .NET Standard library. XmlSerializer doesn't + /// handle Lists or Dictionaries. Do it the old-fashioned way. + /// + public string Serialize() { + Debug.Assert(mDelimiters.Count < 10); + StringBuilder sb = new StringBuilder(); + sb.Append('*'); // if the format changes, start with something else + foreach (KeyValuePair kvp in mDelimiters) { + string name = kvp.Key.ToString(); + AddLenString(sb, name); + AddLenString(sb, kvp.Value.Prefix); + sb.Append(kvp.Value.OpenDelim); + sb.Append(kvp.Value.CloseDelim); + AddLenString(sb, kvp.Value.Suffix); + } + sb.Append('!'); + return sb.ToString(); + } + private void AddLenString(StringBuilder sb, string str) { + sb.Append(str.Length.ToString()); + sb.Append(','); + sb.Append(str); + } + public static DelimiterSet Deserialize(string cereal) { + try { + DelimiterSet delimSet = new DelimiterSet(); + + int offset = 0; + if (cereal[offset++] != '*') { + throw new Exception("missing leading asterisk"); + } + while (cereal[offset] != '!') { + string str = GetLenString(cereal, ref offset); + if (!Enum.TryParse(str, out CharEncoding.Encoding enc)) { + Debug.WriteLine("Ignoring unknown encoding " + str); + enc = CharEncoding.Encoding.Unknown; + } + string prefix = GetLenString(cereal, ref offset); + char open = cereal[offset++]; + char close = cereal[offset++]; + string suffix = GetLenString(cereal, ref offset); + if (enc != CharEncoding.Encoding.Unknown) { + delimSet.Set(enc, new DelimiterDef(prefix, open, close, suffix)); + } + } + return delimSet; + } catch (Exception ex) { + Debug.WriteLine("DelimiterSet deserialization failed: " + ex.Message); + return new DelimiterSet(); + } + } + private static string GetLenString(string str, ref int offset) { + int commaIndex = str.IndexOf(',', offset); + if (commaIndex < 0) { + throw new Exception("no comma in length string"); + } + string lenStr = str.Substring(offset, commaIndex - offset); + int len = int.Parse(lenStr); + string resultStr = str.Substring(commaIndex + 1, len); + offset = commaIndex + 1 + len; + return resultStr; + } + } + + #endregion Text Delimiters private static readonly char[] sHexCharsLower = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' @@ -165,10 +292,10 @@ namespace Asm65 { private string mAddrFormatWithBank; // Character data delimiter format strings, processed from the delimiter patterns. - private string mAsciiDelimFmt; - private string mHighAsciiDelimFmt; - private string mC64PetsciiDelimFmt; - private string mC64ScreenCodeDelimFmt; + private string mCharDelimAsciiFmt; + private string mCharDelimHighAsciiFmt; + private string mCharDelimC64PetsciiFmt; + private string mCharDelimC64ScreenCodeFmt; // Generated opcode strings. The index is the bitwise OR of the opcode value and @@ -299,25 +426,29 @@ namespace Asm65 { } // process the delimiter patterns - mAsciiDelimFmt = PatternToFormat(mFormatConfig.mAsciiDelimPattern); - mHighAsciiDelimFmt = PatternToFormat(mFormatConfig.mHighAsciiDelimPattern); - mC64PetsciiDelimFmt = PatternToFormat(mFormatConfig.mC64PetsciiDelimPattern); - mC64ScreenCodeDelimFmt = PatternToFormat(mFormatConfig.mC64ScreenCodeDelimPattern); + DelimiterSet chrDelim = mFormatConfig.mCharDelimiters; + if (chrDelim == null) { + Debug.WriteLine("NOTE: char delimiters not set"); + chrDelim = DelimiterSet.GetDefaultCharDelimiters(); + } + mCharDelimAsciiFmt = + DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.Ascii)); + mCharDelimHighAsciiFmt = + DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.HighAscii)); + mCharDelimC64PetsciiFmt = + DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.C64Petscii)); + mCharDelimC64ScreenCodeFmt = + DelimiterDefToFormat(chrDelim.Get(CharEncoding.Encoding.C64ScreenCode)); } - private string PatternToFormat(string pat) { - if (string.IsNullOrEmpty(pat)) { - return string.Empty; - } - // Must be exactly one '#'. - int firstHash = pat.IndexOf('#'); - int lastHash = pat.LastIndexOf('#'); - if (firstHash < 0 || firstHash != lastHash) { - Debug.WriteLine("Invalid delimiter pattern '" + pat + "'"); - return string.Empty; - } - - return pat.Replace("#", "{0}"); + private string DelimiterDefToFormat(DelimiterDef def) { + StringBuilder sb = new StringBuilder(); + sb.Append(def.Prefix); + sb.Append(def.OpenDelim); + sb.Append("{0}"); + sb.Append(def.CloseDelim); + sb.Append(def.Suffix); + return sb.ToString(); } /// @@ -417,15 +548,21 @@ namespace Asm65 { CharEncoding.Convert conv; switch (enc) { case CharEncoding.Encoding.Ascii: - fmt = mAsciiDelimFmt; + fmt = mCharDelimAsciiFmt; conv = CharEncoding.ConvertAscii; break; case CharEncoding.Encoding.HighAscii: - fmt = mHighAsciiDelimFmt; + fmt = mCharDelimHighAsciiFmt; conv = CharEncoding.ConvertHighAscii; break; case CharEncoding.Encoding.C64Petscii: + fmt = mCharDelimC64PetsciiFmt; + conv = CharEncoding.ConvertC64Petscii; + break; case CharEncoding.Encoding.C64ScreenCode: + fmt = mCharDelimC64ScreenCodeFmt; + conv = CharEncoding.ConvertC64ScreenCode; + break; default: return FormatHexValue(value, 2); } diff --git a/Asm65/StringOpFormatter.cs b/Asm65/StringOpFormatter.cs index eca272c..c32beae 100644 --- a/Asm65/StringOpFormatter.cs +++ b/Asm65/StringOpFormatter.cs @@ -41,7 +41,7 @@ namespace Asm65 { public bool HasEscapedText { get; private set; } public List Lines { get; private set; } - private Formatter.DelimiterSet mDelimiterSet; + private Formatter.DelimiterDef mDelimiterDef; private RawOutputStyle mRawStyle; private int mMaxOperandLen; @@ -77,23 +77,23 @@ namespace Asm65 { /// Constructor. /// /// Reference to text formatter. - /// String delimiter values. + /// String delimiter values. /// How to format raw byte data. /// Maximum line length. /// Character conversion delegate. - public StringOpFormatter(Formatter formatter, Formatter.DelimiterSet delimiterSet, + public StringOpFormatter(Formatter formatter, Formatter.DelimiterDef delimiterDef, RawOutputStyle byteStyle, int maxOperandLen, CharEncoding.Convert charConv) { mRawStyle = byteStyle; mMaxOperandLen = maxOperandLen; CharConv = charConv; - mDelimiterSet = delimiterSet; + mDelimiterDef = delimiterDef; mBuffer = new char[mMaxOperandLen]; mHexChars = formatter.HexDigits; Lines = new List(); // suffix not used, so we don't expect it to be set to something - Debug.Assert(string.IsNullOrEmpty(mDelimiterSet.Suffix)); + Debug.Assert(string.IsNullOrEmpty(mDelimiterDef.Suffix)); Reset(); } @@ -104,8 +104,8 @@ namespace Asm65 { Lines.Clear(); // Copy the prefix string into the buffer for the first line. - for (int i = 0; i < mDelimiterSet.Prefix.Length; i++) { - mBuffer[mIndex++] = mDelimiterSet.Prefix[i]; + for (int i = 0; i < mDelimiterDef.Prefix.Length; i++) { + mBuffer[mIndex++] = mDelimiterDef.Prefix[i]; } } @@ -118,7 +118,7 @@ namespace Asm65 { Debug.Assert(mState != State.Finished); char ch = CharConv(rawCh); - if (ch == mDelimiterSet.OpenDelim || ch == mDelimiterSet.CloseDelim || + if (ch == mDelimiterDef.OpenDelim || ch == mDelimiterDef.CloseDelim || ch == CharEncoding.UNPRINTABLE_CHAR) { // Must write it as a byte. WriteByte(rawCh); @@ -132,21 +132,21 @@ namespace Asm65 { // We must have 4 chars remaining (comma, open quote, new char, close quote). switch (mState) { case State.StartOfLine: - mBuffer[mIndex++] = mDelimiterSet.OpenDelim; + mBuffer[mIndex++] = mDelimiterDef.OpenDelim; break; case State.InQuote: if (mIndex + 2 > mMaxOperandLen) { Flush(); - mBuffer[mIndex++] = mDelimiterSet.OpenDelim; + mBuffer[mIndex++] = mDelimiterDef.OpenDelim; } break; case State.OutQuote: if (mIndex + 4 > mMaxOperandLen) { Flush(); - mBuffer[mIndex++] = mDelimiterSet.OpenDelim; + mBuffer[mIndex++] = mDelimiterDef.OpenDelim; } else { mBuffer[mIndex++] = ','; - mBuffer[mIndex++] = mDelimiterSet.OpenDelim; + mBuffer[mIndex++] = mDelimiterDef.OpenDelim; } break; default: @@ -179,7 +179,7 @@ namespace Asm65 { if (mIndex + minWidth > mMaxOperandLen) { Flush(); } else { - mBuffer[mIndex++] = mDelimiterSet.CloseDelim; + mBuffer[mIndex++] = mDelimiterDef.CloseDelim; mBuffer[mIndex++] = ','; } break; @@ -220,12 +220,12 @@ namespace Asm65 { switch (mState) { case State.StartOfLine: // empty string; put out a pair of delimiters - mBuffer[mIndex++] = mDelimiterSet.OpenDelim; - mBuffer[mIndex++] = mDelimiterSet.CloseDelim; + mBuffer[mIndex++] = mDelimiterDef.OpenDelim; + mBuffer[mIndex++] = mDelimiterDef.CloseDelim; break; case State.InQuote: // add delimiter and finish - mBuffer[mIndex++] = mDelimiterSet.CloseDelim; + mBuffer[mIndex++] = mDelimiterDef.CloseDelim; break; case State.OutQuote: // just output it diff --git a/SourceGen/AppSettings.cs b/SourceGen/AppSettings.cs index c3e60e8..f82fd3a 100644 --- a/SourceGen/AppSettings.cs +++ b/SourceGen/AppSettings.cs @@ -63,6 +63,8 @@ namespace SourceGen { public const string FMT_EXPRESSION_MODE = "fmt-expression-mode"; public const string FMT_PSEUDO_OP_NAMES = "fmt-pseudo-op-names"; + public const string FMT_CHAR_DELIM = "fmt-char-delim"; + public const string FMT_STRING_DELIM = "fmt-string-delim"; public const string CLIP_LINE_FORMAT = "clip-line-format"; @@ -89,11 +91,6 @@ namespace SourceGen { public const string CDLV_FONT_FAMILY = "cdlv-font-family"; public const string CDLV_FONT_SIZE = "cdlv-font-size"; - public const string CHR_ASCII_DELIM_PAT = "chr-ascii-delim-pat"; - public const string CHR_HIGH_ASCII_DELIM_PAT = "chr-high-ascii-delim-pat"; - public const string CHR_C64_PETSCII_DELIM_PAT = "chr-c64-petscii-delim-pat"; - public const string CHR_C64_SCREEN_CODE_DELIM_PAT = "chr-c64-screen-code-delim-pat"; - // Hex dump viewer settings. public const string HEXD_ASCII_ONLY = "hexd-ascii-only"; public const string HEXD_CHAR_CONV = "hexd-char-conv1"; diff --git a/SourceGen/AsmGen/AsmAcme.cs b/SourceGen/AsmGen/AsmAcme.cs index ac98eed..ecd1724 100644 --- a/SourceGen/AsmGen/AsmAcme.cs +++ b/SourceGen/AsmGen/AsmAcme.cs @@ -190,8 +190,12 @@ namespace SourceGen.AsmGen { config.mFullLineCommentDelimiterBase = ";"; config.mBoxLineCommentDelimiter = ";"; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Common; - config.mAsciiDelimPattern = "'#'"; - config.mHighAsciiDelimPattern = "'#' | $80"; + + Formatter.DelimiterSet charSet = new Formatter.DelimiterSet(); + charSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); + charSet.Set(CharEncoding.Encoding.HighAscii, + new Formatter.DelimiterDef(string.Empty, '\'', '\'', " | $80")); + config.mCharDelimiters = charSet; } // IGenerator diff --git a/SourceGen/AsmGen/AsmCc65.cs b/SourceGen/AsmGen/AsmCc65.cs index 7c1fec2..43947d0 100644 --- a/SourceGen/AsmGen/AsmCc65.cs +++ b/SourceGen/AsmGen/AsmCc65.cs @@ -187,8 +187,12 @@ namespace SourceGen.AsmGen { config.mFullLineCommentDelimiterBase = ";"; config.mBoxLineCommentDelimiter = ";"; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Cc65; - config.mAsciiDelimPattern = "'#'"; - config.mHighAsciiDelimPattern = "'#' | $80"; + + Formatter.DelimiterSet charSet = new Formatter.DelimiterSet(); + charSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); + charSet.Set(CharEncoding.Encoding.HighAscii, + new Formatter.DelimiterDef(string.Empty, '\'', '\'', " | $80")); + config.mCharDelimiters = charSet; } // IGenerator diff --git a/SourceGen/AsmGen/AsmMerlin32.cs b/SourceGen/AsmGen/AsmMerlin32.cs index 90f0650..a1e1c25 100644 --- a/SourceGen/AsmGen/AsmMerlin32.cs +++ b/SourceGen/AsmGen/AsmMerlin32.cs @@ -164,8 +164,10 @@ namespace SourceGen.AsmGen { config.mBoxLineCommentDelimiter = string.Empty; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Merlin; - config.mAsciiDelimPattern = "'#'"; - config.mHighAsciiDelimPattern = "\"#\""; + Formatter.DelimiterSet charSet = new Formatter.DelimiterSet(); + charSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); + charSet.Set(CharEncoding.Encoding.HighAscii, Formatter.DOUBLE_QUOTE_DELIM); + config.mCharDelimiters = charSet; } // IGenerator; executes on background thread @@ -501,7 +503,7 @@ namespace SourceGen.AsmGen { } StringOpFormatter stropf = new StringOpFormatter(SourceFormatter, - new Formatter.DelimiterSet(delim), + new Formatter.DelimiterDef(delim), StringOpFormatter.RawOutputStyle.DenseHex, MAX_OPERAND_LEN, charConv); if (dfd.FormatType == FormatDescriptor.Type.StringDci) { // DCI is awkward because the character encoding flips on the last byte. Rather diff --git a/SourceGen/AsmGen/AsmTass64.cs b/SourceGen/AsmGen/AsmTass64.cs index bb8dec5..1a894ff 100644 --- a/SourceGen/AsmGen/AsmTass64.cs +++ b/SourceGen/AsmGen/AsmTass64.cs @@ -186,8 +186,11 @@ namespace SourceGen.AsmGen { config.mFullLineCommentDelimiterBase = ";"; config.mBoxLineCommentDelimiter = ";"; config.mExpressionMode = Formatter.FormatConfig.ExpressionMode.Common; - config.mAsciiDelimPattern = "'#'"; - config.mHighAsciiDelimPattern = "'#' | $80"; + Formatter.DelimiterSet charSet = new Formatter.DelimiterSet(); + charSet.Set(CharEncoding.Encoding.Ascii, Formatter.SINGLE_QUOTE_DELIM); + charSet.Set(CharEncoding.Encoding.HighAscii, + new Formatter.DelimiterDef(string.Empty, '\'', '\'', " | $80")); + config.mCharDelimiters = charSet; } // IGenerator diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs index 9290efb..45b8318 100644 --- a/SourceGen/MainController.cs +++ b/SourceGen/MainController.cs @@ -310,6 +310,16 @@ namespace SourceGen { mMainWin.CodeListFontFamily.ToString()); settings.SetInt(AppSettings.CDLV_FONT_SIZE, (int)mMainWin.CodeListFontSize); + // Character and string delimiters. + Formatter.DelimiterSet chrDel = Formatter.DelimiterSet.GetDefaultCharDelimiters(); + string chrSer = chrDel.Serialize(); + settings.SetString(AppSettings.FMT_CHAR_DELIM, chrSer); + + Formatter.DelimiterSet strDel = Formatter.DelimiterSet.GetDefaultStringDelimiters(); + string strSer = strDel.Serialize(); + settings.SetString(AppSettings.FMT_STRING_DELIM, strSer); + + // Load the settings file, and merge it into the globals. string runtimeDataDir = RuntimeDataAccess.GetDirectory(); if (runtimeDataDir == null) { @@ -427,18 +437,19 @@ namespace SourceGen { mFormatterConfig.mEndOfLineCommentDelimiter = ";"; mFormatterConfig.mFullLineCommentDelimiterBase = ";"; mFormatterConfig.mBoxLineCommentDelimiter = string.Empty; - mFormatterConfig.mAsciiDelimPattern = - AppSettings.Global.GetString(AppSettings.CHR_ASCII_DELIM_PAT, - Res.Strings.DEFAULT_ASCII_DELIM_PAT); - mFormatterConfig.mHighAsciiDelimPattern = - AppSettings.Global.GetString(AppSettings.CHR_HIGH_ASCII_DELIM_PAT, - Res.Strings.DEFAULT_HIGH_ASCII_DELIM_PAT); - mFormatterConfig.mC64PetsciiDelimPattern = - AppSettings.Global.GetString(AppSettings.CHR_C64_PETSCII_DELIM_PAT, - Res.Strings.DEFAULT_C64_PETSCII_DELIM_PAT); - mFormatterConfig.mC64ScreenCodeDelimPattern = - AppSettings.Global.GetString(AppSettings.CHR_C64_SCREEN_CODE_DELIM_PAT, - Res.Strings.DEFAULT_C64_SCREEN_CODE_DELIM_PAT); + + string chrDelCereal = settings.GetString(AppSettings.FMT_CHAR_DELIM, null); + if (chrDelCereal != null) { + mFormatterConfig.mCharDelimiters = + Formatter.DelimiterSet.Deserialize(chrDelCereal); + } + string strDelCereal = settings.GetString(AppSettings.FMT_STRING_DELIM, null); + if (strDelCereal != null) { + mFormatterConfig.mStringDelimiters = + Formatter.DelimiterSet.Deserialize(strDelCereal); + } + + mOutputFormatter = new Formatter(mFormatterConfig); mOutputFormatterCpuDef = null; @@ -1402,7 +1413,7 @@ namespace SourceGen { } public void HandleCodeListDoubleClick(int row, int col) { - Debug.WriteLine("DCLICK: row=" + row + " col=" + col); + //Debug.WriteLine("DCLICK: row=" + row + " col=" + col); mMainWin.CodeListView_DebugValidateSelectionCount(); // Clicking on some types of lines, such as ORG directives, results in diff --git a/SourceGen/PseudoOp.cs b/SourceGen/PseudoOp.cs index d94f0dd..2ff4230 100644 --- a/SourceGen/PseudoOp.cs +++ b/SourceGen/PseudoOp.cs @@ -312,24 +312,31 @@ namespace SourceGen { int hiddenLeadingBytes = 0; int trailingBytes = 0; StringOpFormatter.ReverseMode revMode = StringOpFormatter.ReverseMode.Forward; + Formatter.DelimiterSet delSet = formatter.Config.mStringDelimiters; + Formatter.DelimiterDef delDef; CharEncoding.Convert charConv; switch (dfd.FormatSubType) { case FormatDescriptor.SubType.Ascii: charConv = CharEncoding.ConvertAscii; + delDef = delSet.Get(CharEncoding.Encoding.Ascii); break; case FormatDescriptor.SubType.HighAscii: charConv = CharEncoding.ConvertHighAscii; + delDef = delSet.Get(CharEncoding.Encoding.HighAscii); break; case FormatDescriptor.SubType.C64Petscii: charConv = CharEncoding.ConvertC64Petscii; + delDef = delSet.Get(CharEncoding.Encoding.C64Petscii); break; case FormatDescriptor.SubType.C64Screen: charConv = CharEncoding.ConvertC64ScreenCode; + delDef = delSet.Get(CharEncoding.Encoding.C64ScreenCode); break; default: Debug.Assert(false); charConv = CharEncoding.ConvertAscii; + delDef = delSet.Get(CharEncoding.Encoding.Ascii); break; } @@ -381,9 +388,7 @@ namespace SourceGen { break; } - Formatter.DelimiterSet delims = new Formatter.DelimiterSet( - "pfx:", '\u201c', '\u201d', string.Empty); - StringOpFormatter stropf = new StringOpFormatter(formatter, delims, + StringOpFormatter stropf = new StringOpFormatter(formatter, delDef, StringOpFormatter.RawOutputStyle.CommaSep, MAX_OPERAND_LEN, charConv); stropf.FeedBytes(data, offset + hiddenLeadingBytes, dfd.Length - hiddenLeadingBytes - trailingBytes, 0, revMode); diff --git a/SourceGen/WpfGui/EditAppSettings.xaml b/SourceGen/WpfGui/EditAppSettings.xaml index 55bee3d..6e2cdc1 100644 --- a/SourceGen/WpfGui/EditAppSettings.xaml +++ b/SourceGen/WpfGui/EditAppSettings.xaml @@ -45,14 +45,13 @@ limitations under the License. - -