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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SourceGen/WpfGui/EditAppSettings.xaml.cs b/SourceGen/WpfGui/EditAppSettings.xaml.cs
index 5e8073a..2fe1c3b 100644
--- a/SourceGen/WpfGui/EditAppSettings.xaml.cs
+++ b/SourceGen/WpfGui/EditAppSettings.xaml.cs
@@ -24,6 +24,7 @@ using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;
+using Asm65;
using CommonUtil;
using AssemblerInfo = SourceGen.AsmGen.AssemblerInfo;
@@ -69,11 +70,12 @@ namespace SourceGen.WpfGui {
/// Tab page enumeration.
///
public enum Tab {
- Unknown = -1,
- CodeView = 0,
- AsmConfig = 1,
- DisplayFormat = 2,
- PseudoOp = 3
+ Unknown = 0,
+ CodeView,
+ TextDelimiters,
+ AsmConfig,
+ DisplayFormat,
+ PseudoOp
}
///
@@ -156,6 +158,7 @@ namespace SourceGen.WpfGui {
private void Window_Loaded(object sender, RoutedEventArgs e) {
Loaded_CodeView();
+ Loaded_TextDelimiters();
Loaded_AsmConfig();
Loaded_DisplayFormat();
Loaded_PseudoOp();
@@ -164,6 +167,9 @@ namespace SourceGen.WpfGui {
case Tab.CodeView:
tabControl.SelectedItem = codeViewTab;
break;
+ case Tab.TextDelimiters:
+ tabControl.SelectedItem = textDelimitersTab;
+ break;
case Tab.AsmConfig:
tabControl.SelectedItem = asmConfigTab;
break;
@@ -199,6 +205,13 @@ namespace SourceGen.WpfGui {
string pseudoCereal = opNames.Serialize();
mSettings.SetString(AppSettings.FMT_PSEUDO_OP_NAMES, pseudoCereal);
+ Formatter.DelimiterSet charSet = ExportDelimiters(mCharDtb);
+ string charCereal = charSet.Serialize();
+ mSettings.SetString(AppSettings.FMT_CHAR_DELIM, charCereal);
+ Formatter.DelimiterSet stringSet = ExportDelimiters(mStringDtb);
+ string stringCereal = stringSet.Serialize();
+ mSettings.SetString(AppSettings.FMT_STRING_DELIM, stringCereal);
+
mMainCtrl.SetAppSettings(mSettings);
AsmGen.AssemblerVersionCache.QueryVersions();
IsDirty = false;
@@ -416,60 +429,126 @@ namespace SourceGen.WpfGui {
}
}
- public string AsciiDelimPat {
- get {
- return mSettings.GetString(AppSettings.CHR_ASCII_DELIM_PAT,
- Res.Strings.DEFAULT_ASCII_DELIM_PAT);
- }
- set {
- mSettings.SetString(AppSettings.CHR_ASCII_DELIM_PAT, value);
- OnPropertyChanged();
- IsDirty = true;
- }
- }
- public string HighAsciiDelimPat {
- get {
- return mSettings.GetString(AppSettings.CHR_HIGH_ASCII_DELIM_PAT,
- Res.Strings.DEFAULT_HIGH_ASCII_DELIM_PAT);
- }
- set {
- mSettings.SetString(AppSettings.CHR_HIGH_ASCII_DELIM_PAT, value);
- OnPropertyChanged();
- IsDirty = true;
- }
- }
- public string PetsciiDelimPat {
- get {
- return mSettings.GetString(AppSettings.CHR_C64_PETSCII_DELIM_PAT,
- Res.Strings.DEFAULT_C64_PETSCII_DELIM_PAT);
- }
- set {
- mSettings.SetString(AppSettings.CHR_C64_PETSCII_DELIM_PAT, value);
- OnPropertyChanged();
- IsDirty = true;
- }
- }
- public string ScreenCodeDelimPat {
- get {
- return mSettings.GetString(AppSettings.CHR_C64_SCREEN_CODE_DELIM_PAT,
- Res.Strings.DEFAULT_C64_SCREEN_CODE_DELIM_PAT);
- }
- set {
- mSettings.SetString(AppSettings.CHR_C64_SCREEN_CODE_DELIM_PAT, value);
- OnPropertyChanged();
- IsDirty = true;
- }
- }
-
- private void DefaultTextDelimitersButton_Click(object sender, RoutedEventArgs e) {
- AsciiDelimPat = Res.Strings.DEFAULT_ASCII_DELIM_PAT;
- HighAsciiDelimPat = Res.Strings.DEFAULT_HIGH_ASCII_DELIM_PAT;
- PetsciiDelimPat = Res.Strings.DEFAULT_C64_PETSCII_DELIM_PAT;
- ScreenCodeDelimPat = Res.Strings.DEFAULT_C64_SCREEN_CODE_DELIM_PAT;
- }
-
#endregion Code View
+ #region Text Delimiters
+
+ private class DelimiterTextBoxes {
+ public CharEncoding.Encoding mEncoding;
+ public TextBox mPrefix;
+ public TextBox mOpen;
+ public TextBox mClose;
+ public TextBox mSuffix;
+
+ public DelimiterTextBoxes(CharEncoding.Encoding enc, TextBox prefix, TextBox open,
+ TextBox close, TextBox suffix) {
+ mEncoding = enc;
+ mPrefix = prefix;
+ mOpen = open;
+ mClose = close;
+ mSuffix = suffix;
+ }
+ }
+ private DelimiterTextBoxes[] mCharDtb;
+ private DelimiterTextBoxes[] mStringDtb;
+
+ private void Loaded_TextDelimiters() {
+ // Map text boxes to delimiter definitions.
+ mCharDtb = new DelimiterTextBoxes[] {
+ new DelimiterTextBoxes(CharEncoding.Encoding.Ascii,
+ chrdAsciiPrefix, chrdAsciiOpen, chrdAsciiClose, chrdAsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.HighAscii,
+ chrdHighAsciiPrefix, chrdHighAsciiOpen, chrdHighAsciiClose, chrdHighAsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.C64Petscii,
+ chrdPetsciiPrefix, chrdPetsciiOpen, chrdPetsciiClose, chrdPetsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.C64ScreenCode,
+ chrdScreenCodePrefix, chrdScreenCodeOpen, chrdScreenCodeClose, chrdScreenCodeSuffix),
+ };
+ mStringDtb = new DelimiterTextBoxes[] {
+ new DelimiterTextBoxes(CharEncoding.Encoding.Ascii,
+ strdAsciiPrefix, strdAsciiOpen, strdAsciiClose, strdAsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.HighAscii,
+ strdHighAsciiPrefix, strdHighAsciiOpen, strdHighAsciiClose, strdHighAsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.C64Petscii,
+ strdPetsciiPrefix, strdPetsciiOpen, strdPetsciiClose, strdPetsciiSuffix),
+ new DelimiterTextBoxes(CharEncoding.Encoding.C64ScreenCode,
+ strdScreenCodePrefix, strdScreenCodeOpen, strdScreenCodeClose, strdScreenCodeSuffix),
+ };
+
+ string charDelimCereal = mSettings.GetString(AppSettings.FMT_CHAR_DELIM, null);
+ Formatter.DelimiterSet chrSet;
+ if (!string.IsNullOrEmpty(charDelimCereal)) {
+ chrSet = Formatter.DelimiterSet.Deserialize(charDelimCereal);
+ } else {
+ chrSet = new Formatter.DelimiterSet();
+ }
+ ImportDelimiters(chrSet, mCharDtb);
+
+ string stringDelimCereal = mSettings.GetString(AppSettings.FMT_STRING_DELIM, null);
+ Formatter.DelimiterSet strSet;
+ if (!string.IsNullOrEmpty(stringDelimCereal)) {
+ strSet = Formatter.DelimiterSet.Deserialize(stringDelimCereal);
+ } else {
+ strSet = new Formatter.DelimiterSet();
+ }
+ ImportDelimiters(strSet, mStringDtb);
+
+ // Create text field listeners. Do this last, so the imports don't set dirty flag.
+ foreach (DelimiterTextBoxes boxes in mCharDtb) {
+ boxes.mPrefix.TextChanged += DelimiterTextChanged;
+ boxes.mOpen.TextChanged += DelimiterTextChanged;
+ boxes.mClose.TextChanged += DelimiterTextChanged;
+ boxes.mSuffix.TextChanged += DelimiterTextChanged;
+ }
+ foreach (DelimiterTextBoxes boxes in mStringDtb) {
+ boxes.mPrefix.TextChanged += DelimiterTextChanged;
+ boxes.mOpen.TextChanged += DelimiterTextChanged;
+ boxes.mClose.TextChanged += DelimiterTextChanged;
+ boxes.mSuffix.TextChanged += DelimiterTextChanged;
+ }
+ }
+
+ // Import delimiters from a DelimiterSet to the text fields.
+ private void ImportDelimiters(Formatter.DelimiterSet delSet, DelimiterTextBoxes[] boxarr) {
+ foreach (DelimiterTextBoxes boxes in boxarr) {
+ Formatter.DelimiterDef def = delSet.Get(boxes.mEncoding);
+ boxes.mPrefix.Text = def.Prefix;
+ boxes.mOpen.Text = "" + def.OpenDelim;
+ boxes.mClose.Text = "" + def.CloseDelim;
+ boxes.mSuffix.Text = def.Suffix;
+ }
+ }
+
+ // Export delimiters from the text fields to a DelimiterSet.
+ private Formatter.DelimiterSet ExportDelimiters(DelimiterTextBoxes[] boxarr) {
+ Formatter.DelimiterSet delSet = new Formatter.DelimiterSet();
+ foreach (DelimiterTextBoxes boxes in boxarr) {
+ char open = boxes.mOpen.Text.Length > 0 ? boxes.mOpen.Text[0] : '!';
+ char close = boxes.mClose.Text.Length > 0 ? boxes.mClose.Text[0] : '!';
+ Formatter.DelimiterDef def = new Formatter.DelimiterDef(
+ boxes.mPrefix.Text, open, close, boxes.mSuffix.Text);
+ delSet.Set(boxes.mEncoding, def);
+ }
+ return delSet;
+ }
+
+ // Invoked when text is changed in any delimiter text box.
+ private void DelimiterTextChanged(object sender, EventArgs e) {
+ IsDirty = true;
+ }
+
+ private void ChrDelDefaultsButton_Click(object sender, RoutedEventArgs e) {
+ Formatter.DelimiterSet chrDel = Formatter.DelimiterSet.GetDefaultCharDelimiters();
+ ImportDelimiters(chrDel, mCharDtb);
+ }
+
+ private void StrDelDefaultsButton_Click(object sender, RoutedEventArgs e) {
+ Formatter.DelimiterSet strDel = Formatter.DelimiterSet.GetDefaultStringDelimiters();
+ ImportDelimiters(strDel, mStringDtb);
+ }
+
+ #endregion Text Delimiters
+
#region Asm Config
public const int ASM_COL_MIN_WIDTH = 1;
@@ -964,6 +1043,7 @@ namespace SourceGen.WpfGui {
}
}
+#if false
///
/// Text entry validation rule for text string delimiter patterns.
///
@@ -980,6 +1060,7 @@ namespace SourceGen.WpfGui {
return ValidationResult.ValidResult;
}
}
+#endif
#endregion Validation rules
}