diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 12b7186bb0..672c0b1184 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -474,9 +474,9 @@ pub fn (a []string) str() string { sb.write('[') for i in 0 .. a.len { val := a[i] - sb.write("\'") + sb.write("'") sb.write(val) - sb.write("\'") + sb.write("'") if i < a.len - 1 { sb.write(', ') } diff --git a/vlib/flag/flag_test.v b/vlib/flag/flag_test.v index ac6b2075bd..7dba1d6a0d 100644 --- a/vlib/flag/flag_test.v +++ b/vlib/flag/flag_test.v @@ -137,7 +137,7 @@ fn test_finalize_returns_error_for_unknown_flags() { mut fp := flag.new_flag_parser(['--known', '--unknown']) fp.bool('known', 0, false, '') finalized := fp.finalize() or { - assert err == "Unknown argument \'unknown\'" + assert err == "Unknown argument 'unknown'" return } assert finalized.len < 0 // expect error to be returned diff --git a/vlib/os/os.v b/vlib/os/os.v index c0f76afe86..90e473f040 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -35,7 +35,7 @@ pub fn cp_all(src string, dst string, overwrite bool) ? { source_path := real_path(src) dest_path := real_path(dst) if !exists(source_path) { - return error("Source path doesn\'t exist") + return error("Source path doesn't exist") } // single file copy if !is_dir(source_path) { diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 1c406fcdca..ef6c8caf83 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -510,7 +510,7 @@ fn (mut v Builder) cc() { if v.pref.os == .ios { ios_sdk := if v.pref.is_ios_simulator { 'iphonesimulator' } else { 'iphoneos' } ios_sdk_path_res := os.exec('xcrun --sdk $ios_sdk --show-sdk-path') or { - panic("Couldn\'t find iphonesimulator") + panic("Couldn't find iphonesimulator") } mut isysroot := ios_sdk_path_res.output.replace('\n', '') ccompiler = 'xcrun --sdk iphoneos clang -isysroot $isysroot' diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index cbebeba7bf..49e5d094f2 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -10,6 +10,7 @@ import strings import v.util const ( + bs = '\\' tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t', ] @@ -1185,15 +1186,28 @@ pub fn (mut f Fmt) expr(node ast.Expr) { f.write('}') } ast.StringLiteral { + use_double_quote := node.val.contains("'") && !node.val.contains('"') if node.is_raw { f.write('r') } else if node.language == table.Language.c { f.write('c') } - if node.val.contains("'") && !node.val.contains('"') { - f.write('"$node.val"') + if node.is_raw { + if use_double_quote { + f.write('"$node.val"') + } else { + f.write("'$node.val'") + } } else { - f.write("'$node.val'") + unescaped_val := node.val.replace('$bs$bs', '\x01').replace_each(["$bs'", "'", + '$bs"', '"']) + if use_double_quote { + s := unescaped_val.replace_each(['\x01', '$bs$bs', '"', '$bs"']) + f.write('"$s"') + } else { + s := unescaped_val.replace_each(['\x01', '$bs$bs', "'", "$bs'"]) + f.write("'$s'") + } } } ast.StringInterLiteral { diff --git a/vlib/v/fmt/tests/string_quotes_expected.vv b/vlib/v/fmt/tests/string_quotes_expected.vv index b1730ce364..5f614909b2 100644 --- a/vlib/v/fmt/tests/string_quotes_expected.vv +++ b/vlib/v/fmt/tests/string_quotes_expected.vv @@ -3,9 +3,8 @@ fn main() { println('This is correct !') println("It's okay") println('This is "too"') - // TODO - // 'I\'m not correctly formatted' => "I'm not correctly formatted" - // "\"Everything on the internet is true\" - Albert Einstein, 1965" => '"Everything on the internet is true" - Albert Einstein, 1965' + println("I'm correctly formatted") + println('"Everything on the internet is true" - Albert Einstein, 1965') println('I\'m out of idea "_"') - // "Definitely out \":'(\"" => 'Definitely out ":\'("' + println('Definitely out ":\'("') } diff --git a/vlib/v/fmt/tests/string_quotes_input.vv b/vlib/v/fmt/tests/string_quotes_input.vv index 6db23a4d87..c8cedb52ad 100644 --- a/vlib/v/fmt/tests/string_quotes_input.vv +++ b/vlib/v/fmt/tests/string_quotes_input.vv @@ -3,9 +3,8 @@ fn main() { println('This is correct !') println("It's okay") println('This is "too"') - // TODO - // 'I\'m not correctly formatted' => "I'm not correctly formatted" - // "\"Everything on the internet is true\" - Albert Einstein, 1965" => '"Everything on the internet is true" - Albert Einstein, 1965' + println('I\'m correctly formatted') + println("\"Everything on the internet is true\" - Albert Einstein, 1965") println('I\'m out of idea "_"') - // "Definitely out \":'(\"" => 'Definitely out ":\'("' + println("Definitely out \":'(\"") } diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index 70bfbb0d60..5261008863 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -44,7 +44,7 @@ fn (g &Gen) type_to_fmt(typ table.Type) string { [.struct_, .array, .array_fixed, .map, .bool, .enum_, .interface_, .sum_type, .function] { return '%.*s\\000' } else if sym.kind == .string { - return "\'%.*s\\000\'" + return "'%.*s\\000'" } else if sym.kind in [.f32, .f64] { return '%g\\000' // g removes trailing zeros unlike %f } else if sym.kind == .u64 { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index f943209dc5..b0f345062e 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1438,7 +1438,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t // cestring returns a V string, properly escaped for embeddeding in a C string literal. fn cestring(s string) string { - return s.replace('\\', '\\\\').replace('"', "\'") + return s.replace('\\', '\\\\').replace('"', "'") } // ctoslit returns a '_SLIT("$s")' call, where s is properly escaped. diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index ca5eb0a77f..b734dca5ce 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1154,7 +1154,7 @@ fn (mut s Scanner) ident_char() string { } } // Escapes a `'` character - return if c == "\'" { + return if c == "'" { '\\' + c } else { c diff --git a/vlib/vweb/tmpl/tmpl.v b/vlib/vweb/tmpl/tmpl.v index d635107d44..27e6b7bece 100644 --- a/vlib/vweb/tmpl/tmpl.v +++ b/vlib/vweb/tmpl/tmpl.v @@ -7,8 +7,8 @@ import os import strings const ( - str_start = "sb.write(\'" - str_end = "\' ) " + str_start = "sb.write('" + str_end = "' ) " ) // compile_file compiles the content of a file by the given path as a template @@ -33,14 +33,14 @@ pub fn compile_template(html_ string, fn_name string) string { h := os.read_file('templates/header.html') or { panic('reading file templates/header.html failed') } - header = h.trim_space().replace("\'", '"') + header = h.trim_space().replace("'", '"') html = header + html } if os.exists('templates/footer.html') && html.contains('@footer') { f := os.read_file('templates/footer.html') or { panic('reading file templates/footer.html failed') } - footer = f.trim_space().replace("\'", '"') + footer = f.trim_space().replace("'", '"') html += footer } mut lines := html.split_into_lines() @@ -81,7 +81,7 @@ _ = footer mut file_content := os.read_file(file_path) or { panic('reading file $file_name failed') } - file_content = file_content.replace("\'", '"') + file_content = file_content.replace("'", '"') lines2 := file_content.split_into_lines() for l in lines2 { lines.insert(i + 1, l)