Skip to content

Commit

Permalink
Fix #451: C/C++/Java printer: escape newlines and other special chara…
Browse files Browse the repository at this point in the history
…cters in String
  • Loading branch information
andreasabel committed Jul 26, 2023
1 parent 836162d commit 77a432f
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 15 deletions.
1 change: 1 addition & 0 deletions source/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Unreleased

* C/C++/Java: escape newline etc. when printing `String` literals [[#449](https://github.com/BNFC/bnfc/issues/449)]
* Haskell/GADT: generated `ComposOp.hs` no longer needs `mtl` library [[#438](https://github.com/BNFC/bnfc/pull/438)]
* Ocaml: fixed a crash in printer with unbalanced `}` [[#439](https://github.com/BNFC/bnfc/issues/439)]
* Ocaml: removed superfluous `let rec` in the printers for token categories
Expand Down
30 changes: 26 additions & 4 deletions source/src/BNFC/Backend/C/CFtoCPrinter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ mkHFile cf groups = unlines
"void shChar(Char c);",
"void shString(String s);",
"void shIdent(String s);",
"void bufEscapeS(const char *s);",
"void bufEscapeC(const char c);",
"void bufAppendS(const char *s);",
"void bufAppendC(const char c);",
"void bufReset(void);",
Expand Down Expand Up @@ -199,7 +201,7 @@ mkCFile cf groups = concat
"void ppString(String s, int i)",
"{",
" bufAppendC('\\\"');",
" bufAppendS(s);",
" bufEscapeS(s);",
" bufAppendC('\\\"');",
" bufAppendC(' ');",
"}",
Expand Down Expand Up @@ -235,13 +237,13 @@ mkCFile cf groups = concat
"void shChar(Char c)",
"{",
" bufAppendC('\\'');",
" bufAppendC(c);",
" bufEscapeC(c);",
" bufAppendC('\\'');",
"}",
"void shString(String s)",
"{",
" bufAppendC('\\\"');",
" bufAppendS(s);",
" bufEscapeS(s);",
" bufAppendC('\\\"');",
"}",
"void shIdent(String s)",
Expand All @@ -257,14 +259,34 @@ mkCFile cf groups = concat
"void sh" ++ t ++ "(String s)",
"{",
" bufAppendC('\\\"');",
" bufAppendS(s);",
" bufEscapeS(s);",
" bufAppendC('\\\"');",
"}",
""
] | t <- tokenNames cf
]
footer = unlines
[
"void bufEscapeS(const char *s)",
"{",
" while (*s) bufEscapeC(*s++);",
"}",
"void bufEscapeC(const char c)",
"{",
" switch(c)",
" {",
" case '\\f': bufAppendS(\"\\\\f\" ); break;",
" case '\\n': bufAppendS(\"\\\\n\" ); break;",
" case '\\r': bufAppendS(\"\\\\r\" ); break;",
" case '\\t': bufAppendS(\"\\\\t\" ); break;",
" case '\\v': bufAppendS(\"\\\\v\" ); break;",
" case '\\\\': bufAppendS(\"\\\\\\\\\"); break;",
" case '\\'': bufAppendS(\"\\\\'\" ); break;",
" case '\\\"': bufAppendS(\"\\\\\\\"\"); break;",
" default: bufAppendC(c);",
" }",
"}",
"",
"void bufAppendS(const char *s)",
"{",
" size_t len = strlen(s);",
Expand Down
38 changes: 30 additions & 8 deletions source/src/BNFC/Backend/CPP/PrettyPrinter.hs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,28 @@ mkHFile useStl inPackage cf groups = unlines
" char *buf_;",
" size_t cur_, buf_size;",
"",
" void inline bufEscape(const char c)",
" {",
" switch(c)",
" {",
" case '\\f': bufAppend(\"\\\\f\" ); break;",
" case '\\n': bufAppend(\"\\\\n\" ); break;",
" case '\\r': bufAppend(\"\\\\r\" ); break;",
" case '\\t': bufAppend(\"\\\\t\" ); break;",
" case '\\v': bufAppend(\"\\\\v\" ); break;",
" case '\\\\': bufAppend(\"\\\\\\\\\"); break;",
" case '\\'': bufAppend(\"\\\\'\" ); break;",
" case '\\\"': bufAppend(\"\\\\\\\"\"); break;",
" default: bufAppend(c);",
" }",
" }",
"",
" void inline bufEscape(const char *s)",
" {",
" while (*s) bufEscape(*s++);",
" }",
"",
if useStl then render (nest 2 $ bufAppendString "bufEscape") else "",
" void inline bufAppend(const char *s)",
" {",
" size_t end = cur_ + strlen(s);",
Expand All @@ -137,7 +159,7 @@ mkHFile useStl inPackage cf groups = unlines
" buf_[++cur_] = 0;",
" }",
"",
if useStl then render (nest 2 bufAppendString) else "",
if useStl then render (nest 2 $ bufAppendString "bufAppend") else "",
" void inline bufReset(void)",
" {",
" if (buf_) delete[] buf_;",
Expand All @@ -160,12 +182,12 @@ mkHFile useStl inPackage cf groups = unlines
"};",
""
]
bufAppendString :: Doc
bufAppendString =
"void inline bufAppend(String str)"
bufAppendString :: Doc -> Doc
bufAppendString f =
"void inline" <+> f <> "(String str)"
$$ codeblock 2
[ "const char *s = str.c_str();"
, "bufAppend(s);"
, f <> "(s);"
]
showHeader = unlines
[
Expand Down Expand Up @@ -303,7 +325,7 @@ mkCFile useStl inPackage cf groups = concat
"void PrintAbsyn::visitString(String s)",
"{",
" bufAppend('\\\"');",
" bufAppend(s);",
" bufEscape(s);",
" bufAppend('\\\"');",
" bufAppend(' ');",
"}",
Expand Down Expand Up @@ -342,13 +364,13 @@ mkCFile useStl inPackage cf groups = concat
"void ShowAbsyn::visitChar(Char c)",
"{",
" bufAppend('\\'');",
" bufAppend(c);",
" bufEscape(c);",
" bufAppend('\\'');",
"}",
"void ShowAbsyn::visitString(String s)",
"{",
" bufAppend('\\\"');",
" bufAppend(s);",
" bufEscape(s);",
" bufAppend('\\\"');",
"}",
"void ShowAbsyn::visitIdent(String s)",
Expand Down
12 changes: 11 additions & 1 deletion source/src/BNFC/Backend/Java/CFtoJavaPrinter15.hs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,17 @@ cf2JavaPrinter packageBase packageAbsyn cf =
" private static void sh(Character c) { render(\"'\" + c.toString() + \"'\"); }",
" private static void sh(String s) { printQuoted(s); }",
"",
" private static void printQuoted(String s) { render(\"\\\"\" + s + \"\\\"\"); }",
" private static void printQuoted(String s) { render(\"\\\"\" + escape(s) + \"\\\"\"); }",
"",
" public static String escape(String s) {",
" return s.replace(\"\\\\\", \"\\\\\\\\\")",
" .replace(\"\\t\", \"\\\\t\")",
" .replace(\"\\b\", \"\\\\b\")",
" .replace(\"\\n\", \"\\\\n\")",
" .replace(\"\\r\", \"\\\\r\")",
" .replace(\"\\f\", \"\\\\f\")",
" .replace(\"\\\"\", \"\\\\\\\"\");",
" }",
"",
" private static void indent()",
" {",
Expand Down
1 change: 1 addition & 0 deletions testing/regression-tests/358_MixFixLists/good01.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ foo
"A".
"B".
"QED".
"line1\nline2".
semi-exprs:
1+1;
2+2;
Expand Down
4 changes: 2 additions & 2 deletions testing/regression-tests/358_MixFixLists/good01.out
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Parse Successful!

[Abstract Syntax]

Top [1,2,3] [Foo,Bar,Baz] ["A","B","QED"] [EPlus (EInt 1) (EInt 1),EPlus (EInt 2) (EInt 2)] [EInt 3,EPlus (EInt 4) (EInt 4)] "ABC"
Top [1,2,3] [Foo,Bar,Baz] ["A","B","QED","line1\nline2"] [EPlus (EInt 1) (EInt 1),EPlus (EInt 2) (EInt 2)] [EInt 3,EPlus (EInt 4) (EInt 4)] "ABC"

[Linearized tree]

Expand All @@ -21,6 +21,6 @@ foo
finally baz
}
}
"A" . "B" . "QED" . semi-exprs: 1 + 1;
"A" . "B" . "QED" . "line1\nline2" . semi-exprs: 1 + 1;
2 + 2;
comma-exprs: 3, (4 + 4), chars: 'A' !, 'B' !, 'C' .
1 change: 1 addition & 0 deletions testing/regression-tests/358_MixFixLists/test.cf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
-- Issue #361, C++ list parsing.
-- Issue #366, render } on new line.
-- Issue #359, Haskell: print Char lists.
-- Issue #449 C/C++/Java: print escape characters in String.

Top. S ::= "{" [Integer]
[FooBar]
Expand Down

0 comments on commit 77a432f

Please sign in to comment.