diff --git a/src/data_scanner_re.cc b/src/data_scanner_re.cc index 3c503cc1..ad5b3764 100644 --- a/src/data_scanner_re.cc +++ b/src/data_scanner_re.cc @@ -1,4 +1,4 @@ -/* Generated by re2c 0.14.2 on Fri Aug 21 06:57:53 2015 */ +/* Generated by re2c 0.14.2 on Wed Aug 26 20:24:23 2015 */ #line 1 "../../lnav2/src/data_scanner_re.re" /** * Copyright (c) 2015, Timothy Stack @@ -209,10 +209,10 @@ yy4: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { - case '"': goto yy951; + case '"': goto yy952; case '%': case '+': goto yy70; - case '\'': goto yy958; + case '\'': goto yy960; case '-': case '.': case '_': goto yy67; @@ -279,7 +279,7 @@ yy4: case 'x': case 'y': case 'z': goto yy462; - case 'e': goto yy964; + case 'e': goto yy967; default: goto yy63; } yy5: @@ -292,10 +292,10 @@ yy6: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { - case '"': goto yy951; + case '"': goto yy952; case '%': case '+': goto yy70; - case '\'': goto yy958; + case '\'': goto yy960; case '-': case '.': case '_': goto yy67; @@ -368,7 +368,7 @@ yy6: yy7: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if (yych >= 0x01) goto yy952; + if (yych >= 0x01) goto yy953; yy8: #line 215 "../../lnav2/src/data_scanner_re.re" { RET(DT_GARBAGE); } @@ -2049,7 +2049,7 @@ yy61: case 24: goto yy442; case 25: goto yy925; case 26: goto yy949; - default: goto yy956; + default: goto yy957; } yy62: yyaccept = 0; @@ -17299,7 +17299,6 @@ yy470: yyaccept = 16; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; -yy471: switch (yych) { case 0x00: case '\t': @@ -17637,7 +17636,7 @@ yy476: yy477: #line 205 "../../lnav2/src/data_scanner_re.re" { RET(DT_CONSTANT); } -#line 17641 "../../lnav2/src/data_scanner_re.cc" +#line 17640 "../../lnav2/src/data_scanner_re.cc" yy478: yych = *++YYCURSOR; switch (yych) { @@ -17890,7 +17889,7 @@ yy482: yy484: #line 145 "../../lnav2/src/data_scanner_re.re" { RET(DT_URL); } -#line 17894 "../../lnav2/src/data_scanner_re.cc" +#line 17893 "../../lnav2/src/data_scanner_re.cc" yy485: YYCTXMARKER = YYCURSOR + 1; yyaccept = 0; @@ -21540,7 +21539,7 @@ yy533: yy534: #line 190 "../../lnav2/src/data_scanner_re.re" { RET(DT_UUID); } -#line 21544 "../../lnav2/src/data_scanner_re.cc" +#line 21543 "../../lnav2/src/data_scanner_re.cc" yy535: YYCTXMARKER = YYCURSOR + 1; yych = *++YYCURSOR; @@ -34660,7 +34659,7 @@ yy765: RET(DT_HEX_DUMP); } } -#line 34664 "../../lnav2/src/data_scanner_re.cc" +#line 34663 "../../lnav2/src/data_scanner_re.cc" yy766: yych = *++YYCURSOR; switch (yych) { @@ -39207,7 +39206,7 @@ yy834: { RET(DT_VERSION_NUMBER); } -#line 39211 "../../lnav2/src/data_scanner_re.cc" +#line 39210 "../../lnav2/src/data_scanner_re.cc" yy835: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); @@ -40886,7 +40885,7 @@ yy858: { RET(DT_IPV4_ADDRESS); } -#line 40890 "../../lnav2/src/data_scanner_re.cc" +#line 40889 "../../lnav2/src/data_scanner_re.cc" yy859: yyaccept = 22; yych = *(YYMARKER = ++YYCURSOR); @@ -41820,7 +41819,7 @@ yy876: { RET(DT_DATE); } -#line 41824 "../../lnav2/src/data_scanner_re.cc" +#line 41823 "../../lnav2/src/data_scanner_re.cc" yy877: yyaccept = 23; yych = *(YYMARKER = ++YYCURSOR); @@ -45251,7 +45250,7 @@ yy923: yy925: #line 192 "../../lnav2/src/data_scanner_re.re" { RET(DT_NUMBER); } -#line 45255 "../../lnav2/src/data_scanner_re.cc" +#line 45254 "../../lnav2/src/data_scanner_re.cc" yy926: yyaccept = 25; YYMARKER = ++YYCURSOR; @@ -46766,7 +46765,13 @@ yy946: default: goto yy944; } yy948: - ++YYCURSOR; + yyaccept = 26; + YYMARKER = ++YYCURSOR; + yych = *YYCURSOR; + switch (yych) { + case '\'': goto yy944; + default: goto yy949; + } yy949: #line 133 "../../lnav2/src/data_scanner_re.re" { @@ -46781,38 +46786,44 @@ yy949: cap[1].c_end -= 1; return true; } -#line 46785 "../../lnav2/src/data_scanner_re.cc" +#line 46790 "../../lnav2/src/data_scanner_re.cc" yy950: yyaccept = 26; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; switch (yych) { case 0x00: goto yy949; - case '\'': goto yy948; + case '\'': goto yy950; case '\\': goto yy946; default: goto yy944; } -yy951: +yy952: ++YYCURSOR; yych = *YYCURSOR; -yy952: +yy953: switch (yych) { case 0x00: goto yy61; - case '"': goto yy955; - case '\\': goto yy953; - default: goto yy951; + case '"': goto yy956; + case '\\': goto yy954; + default: goto yy952; } -yy953: +yy954: ++YYCURSOR; yych = *YYCURSOR; switch (yych) { - case '"': goto yy957; - case '\\': goto yy953; - default: goto yy951; + case '"': goto yy958; + case '\\': goto yy954; + default: goto yy952; } -yy955: - ++YYCURSOR; yy956: + yyaccept = 27; + YYMARKER = ++YYCURSOR; + yych = *YYCURSOR; + switch (yych) { + case '"': goto yy952; + default: goto yy957; + } +yy957: #line 121 "../../lnav2/src/data_scanner_re.re" { CAPTURE(DT_QUOTED_STRING); @@ -46826,18 +46837,18 @@ yy956: cap[1].c_end -= 1; return true; } -#line 46830 "../../lnav2/src/data_scanner_re.cc" -yy957: +#line 46841 "../../lnav2/src/data_scanner_re.cc" +yy958: yyaccept = 27; YYMARKER = ++YYCURSOR; yych = *YYCURSOR; switch (yych) { - case 0x00: goto yy956; - case '"': goto yy955; - case '\\': goto yy953; - default: goto yy951; + case 0x00: goto yy957; + case '"': goto yy958; + case '\\': goto yy954; + default: goto yy952; } -yy958: +yy960: YYCTXMARKER = YYCURSOR + 1; ++YYCURSOR; yych = *YYCURSOR; @@ -46852,12 +46863,12 @@ yy958: case ')': case '*': case ':': - case ';': goto yy960; + case ';': goto yy962; case '!': case ',': - case '?': goto yy961; - case '\'': goto yy963; - case '.': goto yy962; + case '?': goto yy963; + case '\'': goto yy965; + case '.': goto yy964; case '\\': goto yy946; case 'a': case 'b': @@ -46884,15 +46895,15 @@ yy958: case 'w': case 'x': case 'y': - case 'z': goto yy958; + case 'z': goto yy960; default: goto yy944; } -yy960: +yy962: yyaccept = 16; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 0x00) goto yy468; goto yy945; -yy961: +yy963: yyaccept = 16; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { @@ -46900,39 +46911,40 @@ yy961: case '\t': case '\n': case '\r': - case ' ': goto yy960; + case ' ': goto yy962; default: goto yy945; } -yy962: +yy964: yych = *++YYCURSOR; switch (yych) { case '\t': case '\n': case '\r': - case ' ': goto yy960; + case ' ': goto yy962; default: goto yy945; } -yy963: +yy965: YYCTXMARKER = YYCURSOR + 1; yyaccept = 26; - yych = *(YYMARKER = ++YYCURSOR); + YYMARKER = ++YYCURSOR; + yych = *YYCURSOR; switch (yych) { case 0x00: case '\t': case '\n': case '\r': case ' ': - case '!': case '"': - case '\'': case '(': case ')': case '*': - case ',': - case '.': case ':': - case ';': - case '?': + case ';': goto yy467; + case '!': + case ',': + case '?': goto yy469; + case '\'': goto yy966; + case '.': goto yy472; case 'a': case 'b': case 'c': @@ -46958,10 +46970,61 @@ yy963: case 'w': case 'x': case 'y': - case 'z': goto yy471; + case 'z': goto yy465; default: goto yy949; } -yy964: +yy966: + YYCTXMARKER = YYCURSOR + 1; + yyaccept = 16; + YYMARKER = ++YYCURSOR; + yych = *YYCURSOR; + switch (yych) { + case 0x00: goto yy467; + case '\t': + case '\n': + case '\r': + case ' ': + case '"': + case '(': + case ')': + case '*': + case ':': + case ';': goto yy962; + case '!': + case ',': + case '?': goto yy963; + case '\'': goto yy965; + case '.': goto yy964; + case '\\': goto yy946; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy960; + default: goto yy944; + } +yy967: YYCTXMARKER = YYCURSOR + 1; yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); @@ -46982,7 +47045,7 @@ yy964: case '%': case '+': goto yy70; case '\'': goto yy470; - case '-': goto yy965; + case '-': goto yy968; case '.': goto yy475; case '0': case '1': @@ -47051,7 +47114,7 @@ yy964: case 'z': goto yy462; default: goto yy63; } -yy965: +yy968: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { @@ -47122,10 +47185,10 @@ yy965: case 'w': case 'x': case 'y': - case 'z': goto yy966; + case 'z': goto yy969; default: goto yy63; } -yy966: +yy969: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { @@ -47197,10 +47260,10 @@ yy966: case 'w': case 'x': case 'y': - case 'z': goto yy967; + case 'z': goto yy970; default: goto yy63; } -yy967: +yy970: YYCTXMARKER = YYCURSOR + 1; yyaccept = 0; YYMARKER = ++YYCURSOR; @@ -47275,7 +47338,7 @@ yy967: case 'Z': case '_': goto yy67; case '.': goto yy475; - case ':': goto yy969; + case ':': goto yy972; case '@': goto yy69; case 'a': case 'b': @@ -47302,10 +47365,10 @@ yy967: case 'w': case 'x': case 'y': - case 'z': goto yy967; + case 'z': goto yy970; default: goto yy62; } -yy969: +yy972: yyaccept = 16; yych = *(YYMARKER = ++YYCURSOR); switch (yych) { diff --git a/src/data_scanner_re.re b/src/data_scanner_re.re index 3dea7426..62a54aed 100644 --- a/src/data_scanner_re.re +++ b/src/data_scanner_re.re @@ -118,7 +118,7 @@ bool data_scanner::tokenize2(pcre_context &pc, data_token_t &token_out) EOF { return false; } - ("u"|"r")?'"'('\\'.|[^\x00\"])*'"' { + ("u"|"r")?'"'('\\'.|'""'|[^\x00\"])*'"' { CAPTURE(DT_QUOTED_STRING); switch (pi.get_string()[cap[1].c_begin]) { case 'u': @@ -130,7 +130,7 @@ bool data_scanner::tokenize2(pcre_context &pc, data_token_t &token_out) cap[1].c_end -= 1; return true; } - ("u"|"r")?"'"('\\'.|[^\x00\'])*"'" { + ("u"|"r")?"'"('\\'.|"''"|[^\x00\'])*"'" { CAPTURE(DT_QUOTED_STRING); switch (pi.get_string()[cap[1].c_begin]) { case 'u': diff --git a/src/lnav_util.cc b/src/lnav_util.cc index b23bb27b..cd38a43f 100644 --- a/src/lnav_util.cc +++ b/src/lnav_util.cc @@ -70,6 +70,10 @@ std::string hash_string(const std::string &str) size_t unquote(char *dst, const char *str, size_t len) { + if (str[0] == 'r' || str[0] == 'u') { + str += 1; + len -= 1; + } char quote_char = str[0]; size_t index = 0; @@ -80,6 +84,23 @@ size_t unquote(char *dst, const char *str, size_t len) if (str[lpc] == quote_char) { lpc += 1; } + else if (str[lpc] == '\\' && (lpc + 1) < len) { + switch (str[lpc] + 1) { + case 'n': + dst[index] = '\n'; + break; + case 'r': + dst[index] = '\r'; + break; + case 't': + dst[index] = '\t'; + break; + default: + dst[index] = str[lpc + 1]; + break; + } + lpc += 1; + } } dst[index] = '\0'; diff --git a/src/pretty_printer.hh b/src/pretty_printer.hh index 13cfeb6f..905d564c 100644 --- a/src/pretty_printer.hh +++ b/src/pretty_printer.hh @@ -46,6 +46,7 @@ #include "timer.hh" #include "ansi_scrubber.hh" #include "data_scanner.hh" +#include "lnav_util.hh" extern sig_atomic_t reverse_lookup_enabled; @@ -65,8 +66,8 @@ public: pcre_context::capture_t e_capture; }; - pretty_printer(data_scanner *ds) - : pp_leading_indent(0), + pretty_printer(data_scanner *ds, int leading_indent=0) + : pp_leading_indent(leading_indent), pp_depth(0), pp_line_length(0), pp_scanner(ds) { @@ -271,14 +272,29 @@ private: if (this->pp_line_length == 0) { this->append_indent(); } - this->pp_stream << pi.get_substr(&el.e_capture); - switch (el.e_token) { - case DT_IPV4_ADDRESS: - case DT_IPV6_ADDRESS: - this->convert_ip_address(el); - break; - default: - break; + if (el.e_token == DT_QUOTED_STRING) { + pcre_input &pi = this->pp_scanner->get_input(); + auto_mem unquoted_str((char *)malloc(pi.pi_length)); + const char *start = pi.get_substr_start(&el.e_capture); + unquote(unquoted_str.in(), start, el.e_capture.length()); + data_scanner ds(unquoted_str.in()); + pretty_printer str_pp(&ds, this->pp_leading_indent); + std::string result = str_pp.print(); + if (result.find('\n') != std::string::npos) { + this->pp_stream << str_pp.print(); + } else { + this->pp_stream << pi.get_substr(&el.e_capture); + } + } else { + this->pp_stream << pi.get_substr(&el.e_capture); + switch (el.e_token) { + case DT_IPV4_ADDRESS: + case DT_IPV6_ADDRESS: + this->convert_ip_address(el); + break; + default: + break; + } } this->pp_line_length += el.e_capture.length(); if (el.e_token == DT_LINE) { diff --git a/test/Makefile.am b/test/Makefile.am index a489452a..df88c3cc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -254,6 +254,7 @@ dist_noinst_DATA = \ mvwattrline_output.0 \ textfile_json_indented.0 \ textfile_json_one_line.0 \ + textfile_quoted_json.0 \ view_colors_output.0 \ vt52_curses_input.0 \ vt52_curses_input.1 \ diff --git a/test/test_cmds.sh b/test/test_cmds.sh index be77790a..d4542f8c 100644 --- a/test/test_cmds.sh +++ b/test/test_cmds.sh @@ -405,6 +405,24 @@ check_output "pretty-printer is not working for indented text files" <http://openam.vagrant.dev/openam\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\nhttp://openam.vagrant.dev/openam\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n4uSmVzjovUdQd3px/RcnoxQBsqE=\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\nhm/grge36uA6j1OWif2bTcvVTwESjmuJa27NxepW0AiV5YlcsHDl7RAIk6k/CjsSero3bxGbm56m\\\\\\\\nYncOEi9F1Tu7dS0bfx+vhm/kKTPgwZctf4GWn4qQwP+KeoZywbNj9ShsYJ+zPKzXwN4xBSuPjMxP\\\\\\\\nNf5szzjEWpOndQO/uDs=\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\nMIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh\\\\\\\\nbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w\\\\\\\\nZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw\\\\\\\\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK\\\\\\\\nBgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B\\\\\\\\nAQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+\\\\\\\\nRkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY\\\\\\\\nJs0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U\\\\\\\\nQzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA\\\\\\\\ncGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC\\\\\\\\n/FfwWigmrW0Y0Q==\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\nuser@example.com\\\\\\\\n\\\\\\\\n\\\\\\\\n\\\\\\\\nhttp://localhost:8086\\\\\\\\n\\\\\\\\n\\\\\\\\nurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", + "data": "http://localhost:8086|/|http://openam.vagrant.dev/openam\\\\n\\\\n\\\\n\\\\nhttp://openam.vagrant.dev/openam\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n\\\\n4uSmVzjovUdQd3px/RcnoxQBsqE=\\\\n\\\\n\\\\n\\\\nhm/grge36uA6j1OWif2bTcvVTwESjmuJa27NxepW0AiV5YlcsHDl7RAIk6k/CjsSero3bxGbm56m\\\\nYncOEi9F1Tu7dS0bfx+vhm/kKTPgwZctf4GWn4qQwP+KeoZywbNj9ShsYJ+zPKzXwN4xBSuPjMxP\\\\nNf5szzjEWpOndQO/uDs=\\\\n\\\\n\\\\n\\\\n\\\\nMIICQDCCAakCBEeNB0swDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNh\\\\nbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMQwwCgYDVQQKEwNTdW4xEDAOBgNVBAsTB09w\\\\nZW5TU08xDTALBgNVBAMTBHRlc3QwHhcNMDgwMTE1MTkxOTM5WhcNMTgwMTEyMTkxOTM5WjBnMQsw\\\\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExDDAK\\\\nBgNVBAoTA1N1bjEQMA4GA1UECxMHT3BlblNTTzENMAsGA1UEAxMEdGVzdDCBnzANBgkqhkiG9w0B\\\\nAQEFAAOBjQAwgYkCgYEArSQc/U75GB2AtKhbGS5piiLkmJzqEsp64rDxbMJ+xDrye0EN/q1U5Of+\\\\nRkDsaN/igkAvV1cuXEgTL6RlafFPcUX7QxDhZBhsYF9pbwtMzi4A4su9hnxIhURebGEmxKW9qJNY\\\\nJs0Vo5+IgjxuEWnjnnVgHTs1+mq5QYTA7E6ZyL8CAwEAATANBgkqhkiG9w0BAQQFAAOBgQB3Pw/U\\\\nQzPKTPTYi9upbFXlrAKMwtFf2OW4yvGWWvlcwcNSZJmTJ8ARvVYOMEVNbsT4OFcfu2/PeYoAdiDA\\\\ncGy/F2Zuj8XJJpuQRSE6PtQqBuDEHjjmOQJ0rV/r8mO1ZCtHRhpZ5zYRjhRC9eCbjx9VrFax0JDC\\\\n/FfwWigmrW0Y0Q==\\\\n\\\\n\\\\n\\\\n\\\\nuser@example.com\\\\n\\\\n\\\\n\\\\nhttp://localhost:8086\\\\n\\\\n\\\\nurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", "domain": "dc=openam", "hostname": "192.168.33.1\t", "ipaddr": "Not Available", diff --git a/test/textfile_quoted_json.0 b/test/textfile_quoted_json.0 new file mode 100644 index 00000000..cf46f727 --- /dev/null +++ b/test/textfile_quoted_json.0 @@ -0,0 +1 @@ +'{ "foo bar" : null, "array" : [1, 2, 3], "obj" : { "one" : 1, "two" : true } }'