From fdf2a0777cdb9ba23ae7546765832bd150b47d3a Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Thu, 4 Nov 2021 12:59:15 -0700 Subject: [PATCH] Fix trailing backslash issue If an end-of-line comment ended with '\', the code that "prettifies" the JSON output would get confused, and would start inserting \r\n after commas inside comment strings. This didn't corrupt the project files, but it did make them look funny, and required manual cleanup. Added a sample. This won't catch regressions of this particular problem because it only happens when you save the file, but if nothing else it'll act as documentation. --- CommonUtil/TextUtil.cs | 16 +- .../SGTestData/20090-notes-and-comments.dis65 | 161 +++++++++++++++--- .../20090-notes-and-comments_64tass.S | 4 +- .../Expected/20090-notes-and-comments_acme.S | 4 +- .../Expected/20090-notes-and-comments_cc65.S | 4 +- .../20090-notes-and-comments_merlin32.S | 4 +- 6 files changed, 157 insertions(+), 36 deletions(-) diff --git a/CommonUtil/TextUtil.cs b/CommonUtil/TextUtil.cs index 7e26a8c..a133320 100644 --- a/CommonUtil/TextUtil.cs +++ b/CommonUtil/TextUtil.cs @@ -127,15 +127,23 @@ namespace CommonUtil { Debug.Assert(findStrQuote == repStr.Contains('\"')); bool inQuote = false; + bool lastBackSlash = false; for (int i = 0; i < inStr.Length; i++) { char ch = inStr[i]; if (inQuote) { - // Check to see if the double-quote is quoted. It's safe to back up - // one because we don't start in-quote. - if (ch == '\"' && inStr[i-1] != '\\') { + if (lastBackSlash) { + lastBackSlash = false; + // JSON recognizes: \" \\ \/ \b \f \n \r \t \uXXXX + // Ignore them all. Especially important for \", so we don't + // mishandle quoted quotes, and for \\, so we don't fail to handle + // quotes on a string that ends with a backslash. + } else if (ch == '\\') { + lastBackSlash = true; + } else if (ch == '"') { + // Un-quoted quote. End of string. inQuote = false; } else { - // in quoted text, keep going + // Still in quoted string, keep going. } sb.Append(ch); } else { diff --git a/SourceGen/SGTestData/20090-notes-and-comments.dis65 b/SourceGen/SGTestData/20090-notes-and-comments.dis65 index e07fe95..4ca5a4f 100644 --- a/SourceGen/SGTestData/20090-notes-and-comments.dis65 +++ b/SourceGen/SGTestData/20090-notes-and-comments.dis65 @@ -1,53 +1,166 @@ ### 6502bench SourceGen dis65 v1.0 ### { -"_ContentVersion":2,"FileDataLength":98,"FileDataCrc32":-80207687,"ProjectProps":{ -"CpuName":"6502","IncludeUndocumentedInstr":false,"TwoByteBrk":false,"EntryFlags":32702671,"AutoLabelStyle":"Simple","AnalysisParams":{ -"AnalyzeUncategorizedData":true,"DefaultTextScanMode":"LowHighAscii","MinCharsForString":4,"SeekNearbyTargets":true,"SmartPlpHandling":true}, -"PlatformSymbolFileIdentifiers":["RT:TestData/TestSyms.sym65"],"ExtensionScriptFileIdentifiers":[],"ProjectSyms":{ +"_ContentVersion":5, +"FileDataLength":98, +"FileDataCrc32":-80207687, +"ProjectProps":{ +"CpuName":"6502", +"IncludeUndocumentedInstr":false, +"TwoByteBrk":false, +"EntryFlags":32702671, +"AutoLabelStyle":"Simple", +"AnalysisParams":{ +"AnalyzeUncategorizedData":true, +"DefaultTextScanMode":"LowHighAscii", +"MinCharsForString":4, +"SeekNearbyTargets":true, +"UseRelocData":false, +"SmartPlpHandling":true, +"SmartPlbHandling":true}, + +"PlatformSymbolFileIdentifiers":["RT:TestData/TestSyms.sym65"], +"ExtensionScriptFileIdentifiers":[], +"ProjectSyms":{ }}, + "AddressMap":[{ -"Offset":0,"Addr":4096}],"TypeHints":[{ -"Low":0,"High":0,"Hint":"Code"}],"StatusFlagOverrides":{ +"Offset":0, +"Addr":4096, +"Length":-1024, +"PreLabel":"", +"IsRelative":false}], +"TypeHints":[{ +"Low":0, +"High":0, +"Hint":"Code"}], +"StatusFlagOverrides":{ }, + "Comments":{ -"0":"Comment!","2":"\u0026another comment with \u0026\u0026s!","30":"Pull in plataddr to see the comment on the platform file entry.","34":"Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped."}, +"0":"Comment!", +"2":"\u0026another comment with \u0026\u0026s!", +"8":"comment ending in backslash\\", +"10":"comment, with, commas \\\\ \\\" \\/ \\\\\\", +"30":"Pull in plataddr to see the comment on the platform file entry.", +"34":"Comment at the end of a lengthy bulk hex item might overflow various things, but could be wrapped."}, + "LongComments":{ "-2147483647":{ -"Text":"Old school boxed output header. Brk\r\nmultiple lines yay. How about a hy-phenated word?\r\nLooonglonglonglonglonglonglonglonglonglonglongword.\r\n*\r\nThrow in a line divider. These aren\u0027t:\r\n*!\r\n *\r\n\u0026XYZ\r\n\r\n","BoxMode":true,"MaxWidth":40,"BackgroundColor":0}, +"Text":"Old school boxed output header. Brk\r\nmultiple lines yay. How about a hy-phenated word?\r\nLooonglonglonglonglonglonglonglonglonglonglongword.\r\n*\r\nThrow in a line divider. These aren\u0027t:\r\n*!\r\n *\r\n\u0026XYZ\r\n\r\n", +"BoxMode":true, +"MaxWidth":40, +"BackgroundColor":0}, + "0":{ -"Text":"Short, unboxed comment here!! Two spaces after. More hyp-hens?\r\n","BoxMode":false,"MaxWidth":30,"BackgroundColor":0}, +"Text":"Short, unboxed comment here!! Two spaces after. More hyp-hens?\r\n", +"BoxMode":false, +"MaxWidth":30, +"BackgroundColor":0}, + "2":{ -"Text":"Comment rulers can be helpful in findin the edges of notes. Comments are hyph-enatingly fun. Like the note, this goes out to 80 columns.","BoxMode":false,"MaxWidth":80,"BackgroundColor":0}, +"Text":"Comment rulers can be helpful in findin the edges of notes. Comments are hyph-enatingly fun. Like the note, this goes out to 80 columns.", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":0}, + "4":{ -"Text":"Down to 64 columns this time. Why 64? Why not 64. A rose, by any other name, would break the line at the same place. Or hy-phen split.\r\n","BoxMode":false,"MaxWidth":64,"BackgroundColor":0}, +"Text":"Down to 64 columns this time. Why 64? Why not 64. A rose, by any other name, would break the line at the same place. Or hy-phen split.\r\n", +"BoxMode":false, +"MaxWidth":64, +"BackgroundColor":0}, + "6":{ -"Text":"Ah, the classic 40-column limitation... brings back memories. Of, you know, h-yphenated things.","BoxMode":false,"MaxWidth":40,"BackgroundColor":0}, +"Text":"Ah, the classic 40-column limitation... brings back memories. Of, you know, h-yphenated things.", +"BoxMode":false, +"MaxWidth":40, +"BackgroundColor":0}, + "8":{ -"Text":"Thirty columns. \u0027cause forty felt like too many. Oh, hyp-henation!","BoxMode":false,"MaxWidth":30,"BackgroundColor":0}, +"Text":"Thirty columns. \u0027cause forty felt like too many. Oh, hyp-henation!", +"BoxMode":false, +"MaxWidth":30, +"BackgroundColor":0}, + "10":{ -"Text":"Short box comment, 80 cols.","BoxMode":true,"MaxWidth":80,"BackgroundColor":0}, +"Text":"Short box comment, 80 cols.", +"BoxMode":true, +"MaxWidth":80, +"BackgroundColor":0}, + "12":{ -"Text":"\r\nChoppy\r\n\r\nbox\r\n\r\ncomment\r\n\r\n64 cols\r\n\r\n","BoxMode":true,"MaxWidth":64,"BackgroundColor":0}, +"Text":"\r\nChoppy\r\n\r\nbox\r\n\r\ncomment\r\n\r\n64 cols\r\n\r\n", +"BoxMode":true, +"MaxWidth":64, +"BackgroundColor":0}, + "14":{ -"Text":"Some non-ASCII stuff:\r\n†•�␇\r\n(right side of box looks pushed over on-screen because font isn\u0027t fully mono)","BoxMode":true,"MaxWidth":64,"BackgroundColor":0}, +"Text":"Some non-ASCII stuff:\r\n†•�␇\r\n(right side of box looks pushed over on-screen because font isn\u0027t fully mono)", +"BoxMode":true, +"MaxWidth":64, +"BackgroundColor":0}, + "16":{ -"Text":"Specific line break case at end of. Sentence.\r\nAlternate version for semicolon zz. Output.\r\n\r\nSame thing but with three spaces zz. Three!\r\nAgain with the three spces between. Things.\r\n\r\nTry to make it the very last thing.. ","BoxMode":true,"MaxWidth":40,"BackgroundColor":0}}, +"Text":"Specific line break case at end of. Sentence.\r\nAlternate version for semicolon zz. Output.\r\n\r\nSame thing but with three spaces zz. Three!\r\nAgain with the three spces between. Things.\r\n\r\nTry to make it the very last thing.. ", +"BoxMode":true, +"MaxWidth":40, +"BackgroundColor":0}}, + "Notes":{ "0":{ -"Text":"And now, a note.","BoxMode":false,"MaxWidth":80,"BackgroundColor":-7278960}, +"Text":"And now, a note.", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":-7278960}, + "2":{ -"Text":"Another note, this one longer. We don\u0027t get to see where the lines break, which makes it harder to hit the edges.","BoxMode":false,"MaxWidth":80,"BackgroundColor":-5383962}, +"Text":"Another note, this one longer. We don\u0027t get to see where the lines break, which makes it harder to hit the edges.", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":-5383962}, + "4":{ -"Text":"Another day, another note.","BoxMode":false,"MaxWidth":80,"BackgroundColor":-256}, +"Text":"Another day, another note.", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":-256}, + "6":{ -"Text":"Take note!","BoxMode":false,"MaxWidth":80,"BackgroundColor":-18751}, +"Text":"Take note!", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":-18751}, + "8":{ -"Text":"Duly noted.","BoxMode":false,"MaxWidth":80,"BackgroundColor":-23296}}, +"Text":"Duly noted.", +"BoxMode":false, +"MaxWidth":80, +"BackgroundColor":-23296}}, + "UserLabels":{ "34":{ -"Label":"bytes","Value":4130,"Source":"User","Type":"LocalOrGlobalAddr"}}, +"Label":"bytes", +"Value":4130, +"Source":"User", +"Type":"LocalOrGlobalAddr", +"LabelAnno":"None"}}, + "OperandFormats":{ "34":{ -"Length":64,"Format":"Dense","SubFormat":"None","SymbolRef":null}}, +"Length":64, +"Format":"Dense", +"SubFormat":"None", +"SymbolRef":null}}, + "LvTables":{ +}, + +"Visualizations":[], +"VisualizationAnimations":[], +"VisualizationSets":{ +}, + +"RelocList":{ +}, + +"DbrValues":{ }} diff --git a/SourceGen/SGTestData/Expected/20090-notes-and-comments_64tass.S b/SourceGen/SGTestData/Expected/20090-notes-and-comments_64tass.S index c97de79..828ce6d 100644 --- a/SourceGen/SGTestData/Expected/20090-notes-and-comments_64tass.S +++ b/SourceGen/SGTestData/Expected/20090-notes-and-comments_64tass.S @@ -35,11 +35,11 @@ plataddr = $3000 ;address only in platform file ;Thirty columns. 'cause forty ;felt like too many. Oh, hyp- ;henation! - lda #$05 + lda #$05 ;comment ending in backslash\ ;******************************************************************************* ;* Short box comment, 80 cols. * ;******************************************************************************* - lda #$06 + lda #$06 ;comment, with, commas \\ \" \/ \\\ ;*************************************************************** ;* * ;* Choppy * diff --git a/SourceGen/SGTestData/Expected/20090-notes-and-comments_acme.S b/SourceGen/SGTestData/Expected/20090-notes-and-comments_acme.S index 3e04379..dc42c54 100644 --- a/SourceGen/SGTestData/Expected/20090-notes-and-comments_acme.S +++ b/SourceGen/SGTestData/Expected/20090-notes-and-comments_acme.S @@ -35,11 +35,11 @@ plataddr = $3000 ;address only in platform file ;Thirty columns. 'cause forty ;felt like too many. Oh, hyp- ;henation! - lda #$05 + lda #$05 ;comment ending in backslash\ ;******************************************************************************* ;* Short box comment, 80 cols. * ;******************************************************************************* - lda #$06 + lda #$06 ;comment, with, commas \\ \" \/ \\\ ;*************************************************************** ;* * ;* Choppy * diff --git a/SourceGen/SGTestData/Expected/20090-notes-and-comments_cc65.S b/SourceGen/SGTestData/Expected/20090-notes-and-comments_cc65.S index 53c06b5..c6225e5 100644 --- a/SourceGen/SGTestData/Expected/20090-notes-and-comments_cc65.S +++ b/SourceGen/SGTestData/Expected/20090-notes-and-comments_cc65.S @@ -35,11 +35,11 @@ plataddr = $3000 ;address only in platform file ;Thirty columns. 'cause forty ;felt like too many. Oh, hyp- ;henation! - lda #$05 + lda #$05 ;comment ending in backslash\ ;******************************************************************************* ;* Short box comment, 80 cols. * ;******************************************************************************* - lda #$06 + lda #$06 ;comment, with, commas \\ \" \/ \\\ ;*************************************************************** ;* * ;* Choppy * diff --git a/SourceGen/SGTestData/Expected/20090-notes-and-comments_merlin32.S b/SourceGen/SGTestData/Expected/20090-notes-and-comments_merlin32.S index e6a2fd0..2143562 100644 --- a/SourceGen/SGTestData/Expected/20090-notes-and-comments_merlin32.S +++ b/SourceGen/SGTestData/Expected/20090-notes-and-comments_merlin32.S @@ -33,11 +33,11 @@ plataddr equ $3000 ;address only in platform file ;Thirty columns. 'cause forty ;felt like too many. Oh, hyp- ;henation! - lda #$05 + lda #$05 ;comment ending in backslash\ ******************************************************************************** * Short box comment, 80 cols. * ******************************************************************************** - lda #$06 + lda #$06 ;comment, with, commas \\ \" \/ \\\ **************************************************************** * * * Choppy *