mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-28 01:29:29 +00:00
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.
This commit is contained in:
parent
5889f45737
commit
beb1024550
@ -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
|
||||
|
||||
/// <summary>
|
||||
/// Container for string delimiter pieces. Instances are immutable.
|
||||
/// Container for character and string delimiter pieces. Instances are immutable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
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<CharEncoding.Encoding, DelimiterDef> mDelimiters =
|
||||
new Dictionary<CharEncoding.Encoding, DelimiterDef>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the specified DelimiterDef, or a default if not found.
|
||||
/// </summary>
|
||||
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<CharEncoding.Encoding, DelimiterDef> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes a DelimiterSet.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can't use Javascript from a .NET Standard library. XmlSerializer doesn't
|
||||
/// handle Lists or Dictionaries. Do it the old-fashioned way.
|
||||
/// </remarks>
|
||||
public string Serialize() {
|
||||
Debug.Assert(mDelimiters.Count < 10);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append('*'); // if the format changes, start with something else
|
||||
foreach (KeyValuePair<CharEncoding.Encoding, DelimiterDef> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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);
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace Asm65 {
|
||||
public bool HasEscapedText { get; private set; }
|
||||
public List<string> 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.
|
||||
/// </summary>
|
||||
/// <param name="formatter">Reference to text formatter.</param>
|
||||
/// <param name="delimiterSet">String delimiter values.</param>
|
||||
/// <param name="delimiterDef">String delimiter values.</param>
|
||||
/// <param name="byteStyle">How to format raw byte data.</param>
|
||||
/// <param name="maxOperandLen">Maximum line length.</param>
|
||||
/// <param name="charConv">Character conversion delegate.</param>
|
||||
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<string>();
|
||||
|
||||
// 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
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -45,14 +45,13 @@ limitations under the License.
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<GroupBox Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" Header="Column Visibility"
|
||||
<GroupBox Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Header="Column Visibility"
|
||||
Margin="0,0,10,0" Padding="2,0">
|
||||
<StackPanel>
|
||||
<Button Name="showCol0" Content="{}{0} Offset" Width="120" Margin="0,4"
|
||||
@ -86,7 +85,7 @@ limitations under the License.
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Header="Upper Case Display"
|
||||
<GroupBox Grid.Column="1" Grid.Row="1" Header="Upper Case Display"
|
||||
Margin="5,0,5,0" Padding="2,4">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Hexadecimal Values" Margin="0,4"
|
||||
@ -118,113 +117,7 @@ limitations under the License.
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="2" Grid.Row="1" Header="Text Delimiters"
|
||||
Margin="10,0,0,0" Padding="2,0">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<!-- TextBox spacer -->
|
||||
<Thickness x:Key="TBS" Left="6" Top="4" Right="0" Bottom="0"/>
|
||||
<Thickness x:Key="ASC" Left="0" Top="2" Right="0" Bottom="0"/>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="0.95*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Text="ASCII:" Grid.Column="0" Grid.Row="0"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="{StaticResource ASC}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="0"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Margin="{StaticResource TBS}" Width="90" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}">
|
||||
<TextBox.Text>
|
||||
<Binding Path="AsciiDelimPat" UpdateSourceTrigger="PropertyChanged"
|
||||
FallbackValue="[#]">
|
||||
<Binding.ValidationRules>
|
||||
<local:StringDelimiterRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Text="High ASCII:" Grid.Column="0" Grid.Row="1"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="{StaticResource ASC}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="1"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Margin="{StaticResource TBS}" Width="90" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}">
|
||||
<TextBox.Text>
|
||||
<Binding Path="HighAsciiDelimPat" UpdateSourceTrigger="PropertyChanged"
|
||||
FallbackValue="[#]">
|
||||
<Binding.ValidationRules>
|
||||
<local:StringDelimiterRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Text="C64 PETSCII:" Grid.Column="0" Grid.Row="2"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="{StaticResource ASC}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="2"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Margin="{StaticResource TBS}" Width="90" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}">
|
||||
<TextBox.Text>
|
||||
<Binding Path="PetsciiDelimPat" UpdateSourceTrigger="PropertyChanged"
|
||||
FallbackValue="petscii:[#]M">
|
||||
<Binding.ValidationRules>
|
||||
<local:StringDelimiterRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
|
||||
<TextBlock Text="C64 Screen Code:" Grid.Column="0" Grid.Row="3"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Margin="{StaticResource ASC}"/>
|
||||
<TextBox Grid.Column="1" Grid.Row="3"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||
Margin="{StaticResource TBS}" Width="90" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}">
|
||||
<TextBox.Text>
|
||||
<Binding Path="ScreenCodeDelimPat" UpdateSourceTrigger="PropertyChanged"
|
||||
FallbackValue="[#]">
|
||||
<Binding.ValidationRules>
|
||||
<local:StringDelimiterRule ValidatesOnTargetUpdated="True"/>
|
||||
</Binding.ValidationRules>
|
||||
</Binding>
|
||||
</TextBox.Text>
|
||||
</TextBox>
|
||||
</Grid>
|
||||
|
||||
<DockPanel LastChildFill="False">
|
||||
<Button Name="defaultTextDelimitersButton" DockPanel.Dock="Left"
|
||||
Content="Default" Width="70" Margin="0,8,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
Click="DefaultTextDelimitersButton_Click"/>
|
||||
|
||||
<TextBox DockPanel.Dock="Right" IsReadOnly="True"
|
||||
Text="‘’•“”↑«»❰❱"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"
|
||||
FontSize="16"
|
||||
VerticalAlignment="Bottom"/>
|
||||
<TextBlock DockPanel.Dock="Right" Margin="0,0,4,3" VerticalAlignment="Bottom"
|
||||
Text="Sample:"/>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="2" Grid.Row="2" Header="Miscellaneous"
|
||||
<GroupBox Grid.Column="2" Grid.Row="1" Header="Miscellaneous"
|
||||
Margin="10,0,0,0" Padding="2,4">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Add spaces in bytes column"
|
||||
@ -238,6 +131,286 @@ limitations under the License.
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Name="textDelimitersTab" Header="Text Delimiters">
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<!-- TextBox spacer -->
|
||||
<Thickness x:Key="TBS" Left="2" Top="4" Right="0" Bottom="0"/>
|
||||
<Thickness x:Key="ENC" Left="0" Top="3" Right="4" Bottom="3"/>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Margin="4,0,0,0"
|
||||
Text="Configure character and string delimiters. This does not affect source code generation."/>
|
||||
|
||||
<GroupBox Grid.Column="0" Grid.Row="1" Header="Character Operand Delimiters" Margin="4"
|
||||
Padding="2,4">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- decorative lines to set off row/column headers -->
|
||||
<Rectangle Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"
|
||||
VerticalAlignment="Bottom" Height="1"
|
||||
Stroke="LightGray" Fill="Transparent"/>
|
||||
<Rectangle Grid.Column="0" Grid.Row="0" Grid.RowSpan="5"
|
||||
HorizontalAlignment="Right" Width="1"
|
||||
Stroke="LightGray" Fill="Transparent"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="Encoding" Margin="0,2,0,3"/>
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="Prefix" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Grid.Row="0" Text="Open" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="3" Grid.Row="0" Text="Close" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="4" Grid.Row="0" Text="Suffix" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<TextBlock Text="Plain ASCII" Grid.Column="0" Grid.Row="1"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="chrdAsciiPrefix" Grid.Column="1" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdAsciiOpen" Grid.Column="2" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdAsciiClose" Grid.Column="3" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdAsciiSuffix" Grid.Column="4" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="High ASCII" Grid.Column="0" Grid.Row="2"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="chrdHighAsciiPrefix" Grid.Column="1" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdHighAsciiOpen" Grid.Column="2" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdHighAsciiClose" Grid.Column="3" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdHighAsciiSuffix" Grid.Column="4" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="C64 PETSCII" Grid.Column="0" Grid.Row="3"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="chrdPetsciiPrefix" Grid.Column="1" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdPetsciiOpen" Grid.Column="2" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdPetsciiClose" Grid.Column="3" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdPetsciiSuffix" Grid.Column="4" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="C64 Screen Code" Grid.Column="0" Grid.Row="4"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="chrdScreenCodePrefix" Grid.Column="1" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdScreenCodeOpen" Grid.Column="2" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdScreenCodeClose" Grid.Column="3" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="chrdScreenCodeSuffix" Grid.Column="4" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Button Content="Reset To Defaults" Width="120" Margin="0,8,0,0"
|
||||
HorizontalAlignment="Left" Click="ChrDelDefaultsButton_Click"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="1" Grid.Row="1" Header="Text String Delimiters" Margin="4"
|
||||
Padding="2,4">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- decorative lines to set off row/column headers -->
|
||||
<Rectangle Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"
|
||||
VerticalAlignment="Bottom" Height="1"
|
||||
Stroke="LightGray" Fill="Transparent"/>
|
||||
<Rectangle Grid.Column="0" Grid.Row="0" Grid.RowSpan="5"
|
||||
HorizontalAlignment="Right" Width="1"
|
||||
Stroke="LightGray" Fill="Transparent"/>
|
||||
|
||||
<TextBlock Grid.Column="0" Grid.Row="0" Text="Encoding" Margin="0,2,0,3"/>
|
||||
<TextBlock Grid.Column="1" Grid.Row="0" Text="Prefix" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="2" Grid.Row="0" Text="Open" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Grid.Column="3" Grid.Row="0" Text="Close" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
<TextBlock Visibility="Hidden" Grid.Column="4" Grid.Row="0" Text="Suffix" Margin="3,2,3,0"
|
||||
HorizontalAlignment="Center"/>
|
||||
|
||||
<TextBlock Text="Plain ASCII" Grid.Column="0" Grid.Row="1"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="strdAsciiPrefix" Grid.Column="1" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdAsciiOpen" Grid.Column="2" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdAsciiClose" Grid.Column="3" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Visibility="Hidden" Name="strdAsciiSuffix" Grid.Column="4" Grid.Row="1"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="High ASCII" Grid.Column="0" Grid.Row="2"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="strdHighAsciiPrefix" Grid.Column="1" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdHighAsciiOpen" Grid.Column="2" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdHighAsciiClose" Grid.Column="3" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Visibility="Hidden" Name="strdHighAsciiSuffix" Grid.Column="4" Grid.Row="2"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="C64 PETSCII" Grid.Column="0" Grid.Row="3"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="strdPetsciiPrefix" Grid.Column="1" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdPetsciiOpen" Grid.Column="2" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdPetsciiClose" Grid.Column="3" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Visibility="Hidden" Name="strdPetsciiSuffix" Grid.Column="4" Grid.Row="3"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
|
||||
<TextBlock Text="C64 Screen Code" Grid.Column="0" Grid.Row="4"
|
||||
Margin="{StaticResource ENC}"/>
|
||||
<TextBox Name="strdScreenCodePrefix" Grid.Column="1" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="8"
|
||||
Text="01234567"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdScreenCodeOpen" Grid.Column="2" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Name="strdScreenCodeClose" Grid.Column="3" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="20" MaxLength="1"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
<TextBox Visibility="Hidden" Name="strdScreenCodeSuffix" Grid.Column="4" Grid.Row="4"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
||||
Margin="{StaticResource TBS}" Width="65" MaxLength="12"
|
||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||
</Grid>
|
||||
|
||||
<Button Content="Reset To Defaults" Width="120" Margin="0,8,0,0"
|
||||
HorizontalAlignment="Left" Click="StrDelDefaultsButton_Click"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Grid.Column="0" Grid.Row="2" Header="Sample Characters" Margin="4"
|
||||
Padding="2,4">
|
||||
<StackPanel>
|
||||
<TextBox IsReadOnly="True"
|
||||
Text="‘’•“”↑«»❰❱"
|
||||
FontFamily="{StaticResource GeneralMonoFont}" FontSize="16"/>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem Name="asmConfigTab" Header="Asm Config">
|
||||
<StackPanel>
|
||||
<GroupBox Header="Assembler Configuration" Padding="2,4">
|
||||
|
@ -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.
|
||||
/// </summary>
|
||||
public enum Tab {
|
||||
Unknown = -1,
|
||||
CodeView = 0,
|
||||
AsmConfig = 1,
|
||||
DisplayFormat = 2,
|
||||
PseudoOp = 3
|
||||
Unknown = 0,
|
||||
CodeView,
|
||||
TextDelimiters,
|
||||
AsmConfig,
|
||||
DisplayFormat,
|
||||
PseudoOp
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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
|
||||
/// <summary>
|
||||
/// Text entry validation rule for text string delimiter patterns.
|
||||
/// </summary>
|
||||
@ -980,6 +1060,7 @@ namespace SourceGen.WpfGui {
|
||||
return ValidationResult.ValidResult;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion Validation rules
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user