patch 9.1.1459: xxd: coloring output is inefficient Commit: https://github.com/vim/vim/commit/6897f18ee6e5bb78b32c97616e484030fd514750 Author: Emanuel Krollmann <e.krollm...@protonmail.com> Date: Sun Jun 15 16:24:09 2025 +0200 patch 9.1.1459: xxd: coloring output is inefficient Problem: xxd prints color escape sequences for every octet even if the color doesn't change Solution: use separate arrays for colors and text and only print escape sequences when the color changes (Emanuel Krollmann) fixes: #15122 closes: #17535 Signed-off-by: Emanuel Krollmann <e.krollm...@protonmail.com> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/testdir/test_xxd.vim b/src/testdir/test_xxd.vim index 5d739e073..7c3011f75 100644 --- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -444,7 +444,7 @@ func Test_xxd_buffer_overflow() endif new let input = repeat('A', 256) - call writefile(['-9223372036854775808: ' . repeat(" [1;32m41 [0m ", 256) . ' ' . repeat(" [1;32mA [0m", 256)], 'Xxdexpected', 'D') + call writefile(['-9223372036854775808: ' . repeat(" [1;32m41 [0m ", 256) . ' ' . " [1;32m" . repeat('A', 256) . " [0m"], 'Xxdexpected', 'D') exe 'r! printf ' . input . '| ' . s:xxd_cmd . ' -Ralways -g1 -c256 -d -o 9223372036854775808 > Xxdout' call assert_equalfile('Xxdexpected', 'Xxdout') call delete('Xxdout') @@ -560,70 +560,70 @@ call writefile(data,'Xinput') exe '0r! ' . s:xxd_cmd . ' -R always -c 4 ' . ' XXDfile' $d let expected = [ - \ "00000000: [1;37m00 [1;31m01 [0m [1;31m02 [1;31m03 [0m [1;37m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000004: [1;31m04 [1;31m05 [0m [1;31m06 [1;31m07 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000008: [1;31m08 [1;33m09 [0m [1;33m0a [1;31m0b [0m [1;31m. [1;33m. [1;33m. [1;31m. [0m", - \ "0000000c: [1;31m0c [1;33m0d [0m [1;31m0e [1;31m0f [0m [1;31m. [1;33m. [1;31m. [1;31m. [0m", - \ "00000010: [1;31m10 [1;31m11 [0m [1;31m12 [1;31m13 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000014: [1;31m14 [1;31m15 [0m [1;31m16 [1;31m17 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000018: [1;31m18 [1;31m19 [0m [1;31m1a [1;31m1b [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "0000001c: [1;31m1c [1;31m1d [0m [1;31m1e [1;31m1f [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000020: [1;32m20 [1;32m21 [0m [1;32m22 [1;32m23 [0m [1;32m [1;32m! [1;32m\" [1;32m# [0m", - \ "00000024: [1;32m24 [1;32m25 [0m [1;32m26 [1;37m00 [0m [1;32m$ [1;32m% [1;32m& [1;37m. [0m", - \ "00000028: [1;32m28 [1;32m29 [0m [1;32m2a [1;32m2b [0m [1;32m( [1;32m) [1;32m* [1;32m+ [0m", - \ "0000002c: [1;32m2c [1;32m2d [0m [1;32m2e [1;32m2f [0m [1;32m, [1;32m- [1;32m. [1;32m/ [0m", - \ "00000030: [1;32m30 [1;32m31 [0m [1;32m32 [1;32m33 [0m [1;32m0 [1;32m1 [1;32m2 [1;32m3 [0m", - \ "00000034: [1;32m34 [1;32m35 [0m [1;32m36 [1;32m37 [0m [1;32m4 [1;32m5 [1;32m6 [1;32m7 [0m", - \ "00000038: [1;32m38 [1;32m39 [0m [1;32m3a [1;32m3b [0m [1;32m8 [1;32m9 [1;32m: [1;32m; [0m", - \ "0000003c: [1;32m3c [1;32m3d [0m [1;32m3e [1;32m3f [0m [1;32m< [1;32m= [1;32m> [1;32m? [0m", - \ "00000040: [1;32m40 [1;32m41 [0m [1;32m42 [1;32m43 [0m [1;32m@ [1;32mA [1;32mB [1;32mC [0m", - \ "00000044: [1;32m44 [1;32m45 [0m [1;32m46 [1;32m47 [0m [1;32mD [1;32mE [1;32mF [1;32mG [0m", - \ "00000048: [1;32m48 [1;32m49 [0m [1;32m4a [1;32m4b [0m [1;32mH [1;32mI [1;32mJ [1;32mK [0m", - \ "0000004c: [1;32m4c [1;32m4d [0m [1;32m4e [1;32m4f [0m [1;32mL [1;32mM [1;32mN [1;32mO [0m", - \ "00000050: [1;32m50 [1;32m51 [0m [1;32m52 [1;32m53 [0m [1;32mP [1;32mQ [1;32mR [1;32mS [0m", - \ "00000054: [1;32m54 [1;32m55 [0m [1;32m56 [1;32m57 [0m [1;32mT [1;32mU [1;32mV [1;32mW [0m", - \ "00000058: [1;32m58 [1;32m59 [0m [1;32m5a [1;32m5b [0m [1;32mX [1;32mY [1;32mZ [1;32m[ [0m", - \ "0000005c: [1;37m00 [1;32m5d [0m [1;32m5e [1;32m5f [0m [1;37m. [1;32m] [1;32m^ [1;32m_ [0m", - \ "00000060: [1;32m60 [1;32m61 [0m [1;32m62 [1;32m63 [0m [1;32m` [1;32ma [1;32mb [1;32mc [0m", - \ "00000064: [1;32m64 [1;32m65 [0m [1;32m66 [1;32m67 [0m [1;32md [1;32me [1;32mf [1;32mg [0m", - \ "00000068: [1;32m68 [1;32m69 [0m [1;32m6a [1;32m6b [0m [1;32mh [1;32mi [1;32mj [1;32mk [0m", - \ "0000006c: [1;32m6c [1;32m6d [0m [1;32m6e [1;32m6f [0m [1;32ml [1;32mm [1;32mn [1;32mo [0m", - \ "00000070: [1;32m70 [1;32m71 [0m [1;32m72 [1;32m73 [0m [1;32mp [1;32mq [1;32mr [1;32ms [0m", - \ "00000074: [1;32m74 [1;32m75 [0m [1;32m76 [1;32m77 [0m [1;32mt [1;32mu [1;32mv [1;32mw [0m", - \ "00000078: [1;32m78 [1;32m79 [0m [1;32m7a [1;32m7b [0m [1;32mx [1;32my [1;32mz [1;32m{ [0m", - \ "0000007c: [1;32m7c [1;32m7d [0m [1;32m7e [1;31m7f [0m [1;32m| [1;32m} [1;32m~ [1;31m. [0m", - \ "00000080: [1;31m80 [1;31m81 [0m [1;31m82 [1;31m83 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000084: [1;31m84 [1;31m85 [0m [1;31m86 [1;31m87 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000088: [1;31m88 [1;31m89 [0m [1;31m8a [1;31m8b [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "0000008c: [1;31m8c [1;31m8d [0m [1;31m8e [1;31m8f [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000090: [1;31m90 [1;31m91 [0m [1;31m92 [1;31m93 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000094: [1;31m94 [1;31m95 [0m [1;31m96 [1;31m97 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "00000098: [1;31m98 [1;31m99 [0m [1;31m9a [1;31m9b [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "0000009c: [1;31m9c [1;31m9d [0m [1;31m9e [1;31m9f [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000a0: [1;31ma0 [1;31ma1 [0m [1;31ma2 [1;31ma3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000a4: [1;31ma4 [1;31ma5 [0m [1;31ma6 [1;31ma7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000a8: [1;31ma8 [1;31ma9 [0m [1;31maa [1;31mab [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000ac: [1;31mac [1;31mad [0m [1;31mae [1;31maf [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000b0: [1;31mb0 [1;31mb1 [0m [1;31mb2 [1;31mb3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000b4: [1;31mb4 [1;31mb5 [0m [1;31mb6 [1;31mb7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000b8: [1;31mb8 [1;31mb9 [0m [1;31mba [1;31mbb [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000bc: [1;31mbc [1;31mbd [0m [1;31mbe [1;31mbf [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000c0: [1;31mc0 [1;31mc1 [0m [1;31mc2 [1;31mc3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000c4: [1;31mc4 [1;31mc5 [0m [1;31mc6 [1;31mc7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000c8: [1;31mc8 [1;31mc9 [0m [1;31mca [1;31mcb [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000cc: [1;31mcc [1;31mcd [0m [1;31mce [1;31mcf [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000d0: [1;31md0 [1;31md1 [0m [1;31md2 [1;31md3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000d4: [1;31md4 [1;31md5 [0m [1;31md6 [1;31md7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000d8: [1;31md8 [1;31md9 [0m [1;31mda [1;31mdb [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000dc: [1;31mdc [1;31mdd [0m [1;31mde [1;31mdf [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000e0: [1;31me0 [1;31me1 [0m [1;31me2 [1;31me3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000e4: [1;31me4 [1;31me5 [0m [1;31me6 [1;31me7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000e8: [1;31me8 [1;31me9 [0m [1;31mea [1;31meb [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000ec: [1;31mec [1;31med [0m [1;31mee [1;31mef [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000f0: [1;31mf0 [1;31mf1 [0m [1;31mf2 [1;31mf3 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000f4: [1;31mf4 [1;31mf5 [0m [1;31mf6 [1;31mf7 [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000f8: [1;31mf8 [1;31mf9 [0m [1;31mfa [1;31mfb [0m [1;31m. [1;31m. [1;31m. [1;31m. [0m", - \ "000000fc: [1;31mfc [1;31mfd [0m [1;31mfe [1;34mff [0m [1;31m. [1;31m. [1;31m. [1;34m. [0m"] + \ "00000000: [1;37m00 [1;31m01 [0m [1;31m0203 [0m [1;37m. [1;31m... [0m", + \ "00000004: [1;31m0405 [0m [1;31m0607 [0m [1;31m.... [0m", + \ "00000008: [1;31m08 [1;33m09 [0m [1;33m0a [1;31m0b [0m [1;31m. [1;33m.. [1;31m. [0m", + \ "0000000c: [1;31m0c [1;33m0d [0m [1;31m0e0f [0m [1;31m. [1;33m. [1;31m.. [0m", + \ "00000010: [1;31m1011 [0m [1;31m1213 [0m [1;31m.... [0m", + \ "00000014: [1;31m1415 [0m [1;31m1617 [0m [1;31m.... [0m", + \ "00000018: [1;31m1819 [0m [1;31m1a1b [0m [1;31m.... [0m", + \ "0000001c: [1;31m1c1d [0m [1;31m1e1f [0m [1;31m.... [0m", + \ "00000020: [1;32m2021 [0m [1;32m2223 [0m [1;32m !\"# [0m", + \ "00000024: [1;32m2425 [0m [1;32m26 [1;37m00 [0m [1;32m$%& [1;37m. [0m", + \ "00000028: [1;32m2829 [0m [1;32m2a2b [0m [1;32m()*+ [0m", + \ "0000002c: [1;32m2c2d [0m [1;32m2e2f [0m [1;32m,-./ [0m", + \ "00000030: [1;32m3031 [0m [1;32m3233 [0m [1;32m0123 [0m", + \ "00000034: [1;32m3435 [0m [1;32m3637 [0m [1;32m4567 [0m", + \ "00000038: [1;32m3839 [0m [1;32m3a3b [0m [1;32m89:; [0m", + \ "0000003c: [1;32m3c3d [0m [1;32m3e3f [0m [1;32m<=>? [0m", + \ "00000040: [1;32m4041 [0m [1;32m4243 [0m [1;32m@ABC [0m", + \ "00000044: [1;32m4445 [0m [1;32m4647 [0m [1;32mDEFG [0m", + \ "00000048: [1;32m4849 [0m [1;32m4a4b [0m [1;32mHIJK [0m", + \ "0000004c: [1;32m4c4d [0m [1;32m4e4f [0m [1;32mLMNO [0m", + \ "00000050: [1;32m5051 [0m [1;32m5253 [0m [1;32mPQRS [0m", + \ "00000054: [1;32m5455 [0m [1;32m5657 [0m [1;32mTUVW [0m", + \ "00000058: [1;32m5859 [0m [1;32m5a5b [0m [1;32mXYZ[ [0m", + \ "0000005c: [1;37m00 [1;32m5d [0m [1;32m5e5f [0m [1;37m. [1;32m]^_ [0m", + \ "00000060: [1;32m6061 [0m [1;32m6263 [0m [1;32m`abc [0m", + \ "00000064: [1;32m6465 [0m [1;32m6667 [0m [1;32mdefg [0m", + \ "00000068: [1;32m6869 [0m [1;32m6a6b [0m [1;32mhijk [0m", + \ "0000006c: [1;32m6c6d [0m [1;32m6e6f [0m [1;32mlmno [0m", + \ "00000070: [1;32m7071 [0m [1;32m7273 [0m [1;32mpqrs [0m", + \ "00000074: [1;32m7475 [0m [1;32m7677 [0m [1;32mtuvw [0m", + \ "00000078: [1;32m7879 [0m [1;32m7a7b [0m [1;32mxyz{ [0m", + \ "0000007c: [1;32m7c7d [0m [1;32m7e [1;31m7f [0m [1;32m|}~ [1;31m. [0m", + \ "00000080: [1;31m8081 [0m [1;31m8283 [0m [1;31m.... [0m", + \ "00000084: [1;31m8485 [0m [1;31m8687 [0m [1;31m.... [0m", + \ "00000088: [1;31m8889 [0m [1;31m8a8b [0m [1;31m.... [0m", + \ "0000008c: [1;31m8c8d [0m [1;31m8e8f [0m [1;31m.... [0m", + \ "00000090: [1;31m9091 [0m [1;31m9293 [0m [1;31m.... [0m", + \ "00000094: [1;31m9495 [0m [1;31m9697 [0m [1;31m.... [0m", + \ "00000098: [1;31m9899 [0m [1;31m9a9b [0m [1;31m.... [0m", + \ "0000009c: [1;31m9c9d [0m [1;31m9e9f [0m [1;31m.... [0m", + \ "000000a0: [1;31ma0a1 [0m [1;31ma2a3 [0m [1;31m.... [0m", + \ "000000a4: [1;31ma4a5 [0m [1;31ma6a7 [0m [1;31m.... [0m", + \ "000000a8: [1;31ma8a9 [0m [1;31maaab [0m [1;31m.... [0m", + \ "000000ac: [1;31macad [0m [1;31maeaf [0m [1;31m.... [0m", + \ "000000b0: [1;31mb0b1 [0m [1;31mb2b3 [0m [1;31m.... [0m", + \ "000000b4: [1;31mb4b5 [0m [1;31mb6b7 [0m [1;31m.... [0m", + \ "000000b8: [1;31mb8b9 [0m [1;31mbabb [0m [1;31m.... [0m", + \ "000000bc: [1;31mbcbd [0m [1;31mbebf [0m [1;31m.... [0m", + \ "000000c0: [1;31mc0c1 [0m [1;31mc2c3 [0m [1;31m.... [0m", + \ "000000c4: [1;31mc4c5 [0m [1;31mc6c7 [0m [1;31m.... [0m", + \ "000000c8: [1;31mc8c9 [0m [1;31mcacb [0m [1;31m.... [0m", + \ "000000cc: [1;31mcccd [0m [1;31mcecf [0m [1;31m.... [0m", + \ "000000d0: [1;31md0d1 [0m [1;31md2d3 [0m [1;31m.... [0m", + \ "000000d4: [1;31md4d5 [0m [1;31md6d7 [0m [1;31m.... [0m", + \ "000000d8: [1;31md8d9 [0m [1;31mdadb [0m [1;31m.... [0m", + \ "000000dc: [1;31mdcdd [0m [1;31mdedf [0m [1;31m.... [0m", + \ "000000e0: [1;31me0e1 [0m [1;31me2e3 [0m [1;31m.... [0m", + \ "000000e4: [1;31me4e5 [0m [1;31me6e7 [0m [1;31m.... [0m", + \ "000000e8: [1;31me8e9 [0m [1;31meaeb [0m [1;31m.... [0m", + \ "000000ec: [1;31meced [0m [1;31meeef [0m [1;31m.... [0m", + \ "000000f0: [1;31mf0f1 [0m [1;31mf2f3 [0m [1;31m.... [0m", + \ "000000f4: [1;31mf4f5 [0m [1;31mf6f7 [0m [1;31m.... [0m", + \ "000000f8: [1;31mf8f9 [0m [1;31mfafb [0m [1;31m.... [0m", + \ "000000fc: [1;31mfcfd [0m [1;31mfe [1;34mff [0m [1;31m... [1;34m. [0m"] call assert_equal(expected, getline(1,'$'), s:Mess(s:test)) call delete('Xinput') diff --git a/src/version.c b/src/version.c index 570a0886c..327e8c85a 100644 --- a/src/version.c +++ b/src/version.c @@ -709,6 +709,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1459, /**/ 1458, /**/ diff --git a/src/xxd/xxd.c b/src/xxd/xxd.c index 072ef630a..3e7c54b42 100644 --- a/src/xxd/xxd.c +++ b/src/xxd/xxd.c @@ -67,6 +67,7 @@ * 19.10.2024 -e did add an extra space #15899 * 11.11.2024 improve end-of-options argument parser #9285 * 07.12.2024 fix overflow with xxd --autoskip and large sparse files #16175 + * 15.06.2025 improve color code logic * (c) 1990-1998 by Juergen Weigert (jnwei...@gmail.com) @@ -147,7 +148,7 @@ extern void perror __P((char *)); # endif #endif -char version[] = "xxd 2024-12-07 by Juergen Weigert et al."; +char version[] = "xxd 2025-06-15 by Juergen Weigert et al."; #ifdef WIN32 char osver[] = " (Win32)"; #else @@ -221,6 +222,18 @@ char osver[] = ""; + 12 * COLS /* ASCII dump with colors */ \ + 2) /* " + * LLEN_NO_COLOR is the maximum length of a line excluding the colors. + */ +#define LLEN_NO_COLOR \ + (39 /* addr: log10(ULONG_MAX) if "-d" flag given. We assume ULONG_MAX = 2**128 */ \ + + 2 /* ": " */ \ + + 2 * COLS /* hex dump */ \ + + (COLS - 1) /* whitespace between groups if "-g1" option given and "-c" maxed out */ \ + + 2 /* whitespace */ \ + + COLS /* ASCII dump */ \ + + 2) /* " char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; /* the different hextypes known by this program: */ @@ -232,18 +245,20 @@ char hexxa[] = "0123456789abcdef0123456789ABCDEF", *hexx = hexxa; #define CONDITIONAL_CAPITALIZE(c) (capitalize ? toupper((unsigned char)(c)) : (c)) -#define COLOR_PROLOGUE \ -l[c++] = ' '; \ -l[c++] = '['; \ -l[c++] = '1'; \ -l[c++] = ';'; \ -l[c++] = '3'; +#define COLOR_PROLOGUE(color) \ +l_colored[c++] = ' '; \ +l_colored[c++] = '['; \ +l_colored[c++] = '1'; \ +l_colored[c++] = ';'; \ +l_colored[c++] = '3'; \ +l_colored[c++] = (color); \ +l_colored[c++] = 'm'; #define COLOR_EPILOGUE \ -l[c++] = ' '; \ -l[c++] = '['; \ -l[c++] = '0'; \ -l[c++] = 'm'; +l_colored[c++] = ' '; \ +l_colored[c++] = '['; \ +l_colored[c++] = '0'; \ +l_colored[c++] = 'm'; #define COLOR_RED '1' #define COLOR_GREEN '2' #define COLOR_YELLOW '3' @@ -515,8 +530,54 @@ huntype( return 0; + * Print line l with given colors. + */ + static void +print_colored_line(FILE *fp, char *l, char *colors) + static char l_colored[LLEN+1]; + if (colors) + { + int c = 0; + if (colors[0]) COLOR_PROLOGUE(colors[0]) + l_colored[c++] = l[0]; + int i; + for (i = 1; l[i]; i++) if (colors[i] != colors[i-1]) { if (colors[i-1]) COLOR_EPILOGUE if (colors[i]) COLOR_PROLOGUE(colors[i]) } l_colored[c++] = l[i]; + if (colors[i]) COLOR_EPILOGUE + l_colored[c++] = ' + fputs_or_die(l_colored, fp); + } + else + fputs_or_die(l, fp); - * Print line l. If nz is false, xxdline regards the line as a line of + * Print line l with given colors. If nz is false, xxdline regards the line as a line of * zeroes. If there are three or more consecutive lines of zeroes, * they are replaced by a single '*' character. @@ -528,13 +589,17 @@ huntype( * If nz is always positive, lines are never suppressed. */ static void -xxdline(FILE *fp, char *l, int nz) +xxdline(FILE *fp, char *l, char *colors, int nz) - static char z[LLEN+1]; + static char z[LLEN_NO_COLOR+1]; + static char z_colors[LLEN_NO_COLOR+1]; static signed char zero_seen = 0; if (!nz && zero_seen == 1) - strcpy(z, l); + { + strcpy(z, l); + memcpy(z_colors, colors, strlen(z)); + } if (nz || !zero_seen++) { @@ -543,12 +608,13 @@ xxdline(FILE *fp, char *l, int nz) if (nz < 0) zero_seen--; if (zero_seen == 2) fputs_or_die(z, fp); print_colored_line(fp, z, z_colors); if (zero_seen > 2) fputs_or_die("* ", fp); if (nz >= 0 || zero_seen > 0) fputs_or_die(l, fp); print_colored_line(fp, l, colors); if (nz) zero_seen = 0; } @@ -589,8 +655,8 @@ static unsigned char etoa64[] = 0070,0071,0372,0373,0374,0375,0376,0377 - static void -begin_coloring_char (char *l, int *c, int e, int ebcdic) + static char +get_color_char (int e, int ebcdic) if (ebcdic) { @@ -601,37 +667,37 @@ begin_coloring_char (char *l, int *c, int e, int ebcdic) (e >= 208 && e <= 217) || (e >= 226 && e <= 233) || (e >= 240 && e <= 249) || (e == 189) || (e == 64) || (e == 173) || (e == 224) ) l[(*c)++] = COLOR_GREEN; return COLOR_GREEN; else if (e == 37 || e == 13 || e == 5) l[(*c)++] = COLOR_YELLOW; return COLOR_YELLOW; else if (e == 0) l[(*c)++] = COLOR_WHITE; return COLOR_WHITE; else if (e == 255) l[(*c)++] = COLOR_BLUE; return COLOR_BLUE; else l[(*c)++] = COLOR_RED; return COLOR_RED; } else /* ASCII */ { #if defined(__MVS__) && __CHARSET_LIB == 0 if (e >= 64) l[(*c)++] = COLOR_GREEN; return COLOR_GREEN; #else if (e > 31 && e < 127) l[(*c)++] = COLOR_GREEN; return COLOR_GREEN; #endif else if (e == 9 || e == 10 || e == 13) l[(*c)++] = COLOR_YELLOW; return COLOR_YELLOW; else if (e == 0) l[(*c)++] = COLOR_WHITE; return COLOR_WHITE; else if (e == 255) l[(*c)++] = COLOR_BLUE; return COLOR_BLUE; else l[(*c)++] = COLOR_RED; return COLOR_RED; } - l[(*c)++] = 'm'; + return 0; static int @@ -664,15 +730,17 @@ main(int argc, char *argv[]) int capitalize = 0, decimal_offset = 0; int ebcdic = 0; int octspergrp = -1; /* number of octets grouped in output */ - int grplen; /* total chars per octet group */ + int grplen; /* total chars per octet group excluding colors */ long length = -1, n = 0, seekoff = 0; unsigned long displayoff = 0; - static char l[LLEN+1]; /* static because it may be too big for stack */ + static char l[LLEN_NO_COLOR+1]; /* static because it may be too big for stack */ + static char colors[LLEN_NO_COLOR+1]; /* color array */ char *pp; char *varname = NULL; int addrlen = 9; int color = 0; char *no_color; + char cur_color = 0; no_color = getenv("NO_COLOR"); if (no_color == NULL || no_color[0] == ' @@ -1064,8 +1132,6 @@ main(int argc, char *argv[]) if (hextype != HEX_BITS) { grplen = octspergrp + octspergrp + 1; /* chars per octet group */ - if (color) grplen += 11 * octspergrp; /* color-code needs 11 extra characters */ } else /* hextype == HEX_BITS */ grplen = 8 * octspergrp + 1; @@ -1076,7 +1142,7 @@ main(int argc, char *argv[]) addrlen = sprintf(l, decimal_offset ? "%08ld:" : "%08lx:", ((unsigned long)(n + seekoff + displayoff))); for (c = addrlen; c < LLEN; l[c++] = ' ') for (c = addrlen; c < LLEN_NO_COLOR; l[c++] = ' ') ; x = hextype == HEX_LITTLEENDIAN ? p ^ (octspergrp-1) : p; @@ -1085,17 +1151,13 @@ main(int argc, char *argv[]) if (color) { COLOR_PROLOGUE begin_coloring_char(l,&c,e,ebcdic); l[c++] = hexx[(e >> 4) & 0xf]; l[c++] = hexx[e & 0xf]; COLOR_EPILOGUE } else /*No colors*/ { l[c] = hexx[(e >> 4) & 0xf]; l[++c] = hexx[e & 0xf]; cur_color = get_color_char(e, ebcdic); colors[c] = cur_color; colors[c+1] = cur_color; } l[c] = hexx[(e >> 4) & 0xf]; l[++c] = hexx[e & 0xf]; else /* hextype == HEX_BITS */ @@ -1104,60 +1166,43 @@ main(int argc, char *argv[]) if (e) nonzero++; - /* When changing this update definition of LLEN above. */ + /* When changing this update definition of LLEN and LLEN_NO_COLOR above. */ if (hextype == HEX_LITTLEENDIAN) /* last group will be fully used, round up */ c = grplen * ((cols + octspergrp - 1) / octspergrp); else c = (grplen * cols - 1) / octspergrp; + if (ebcdic) e = (e < 64) ? '.' : etoa64[e-64]; + if (hextype == HEX_LITTLEENDIAN) c -= 1; + c += addrlen + 3 + p; if (color) if (hextype == HEX_BITS) c += addrlen + 3 + p*12; else c = addrlen + 3 + (grplen * cols - 1)/octspergrp + p*12; COLOR_PROLOGUE begin_coloring_char(l,&c,e,ebcdic); colors[c] = cur_color; + l[c++] = #if defined(__MVS__) && __CHARSET_LIB == 0 if (e >= 64) l[c++] = e; else l[c++] = '.'; (e >= 64) #else if (ebcdic) e = (e < 64) ? '.' : etoa64[e-64]; l[c++] = (e > 31 && e < 127) ? e : '.'; (e > 31 && e < 127) #endif COLOR_EPILOGUE - else /*no colors*/ ? e : '.'; + n++; + if (++p == cols) if (ebcdic) e = (e < 64) ? '.' : etoa64[e-64]; l[c++] = ' l[c] = ' if (hextype == HEX_LITTLEENDIAN) c -= 1; c += addrlen + 3 + p; l[c++] = -#if defined(__MVS__) && __CHARSET_LIB == 0 (e >= 64) -#else (e > 31 && e < 127) -#endif ? e : '.'; xxdline(fpo, l, color ? colors : NULL, autoskip ? nonzero : 1); memset(colors, 0, c); nonzero = 0; p = 0; n++; if (++p == cols) l[c++] = ' l[c] = ' xxdline(fpo, l, autoskip ? nonzero : 1); nonzero = 0; p = 0; } if (p) { @@ -1175,11 +1220,8 @@ main(int argc, char *argv[]) for (i = 0; i < fill;i++) COLOR_PROLOGUE l[c++] = COLOR_RED; l[c++] = 'm'; colors[c] = COLOR_RED; l[c++] = ' '; /* empty space */ COLOR_EPILOGUE x++; p++; @@ -1193,18 +1235,17 @@ main(int argc, char *argv[]) for (i = cols - p; i > 0;i--) COLOR_PROLOGUE l[c++] = COLOR_RED; l[c++] = 'm'; colors[c] = COLOR_RED; l[c++] = ' '; /* empty space */ COLOR_EPILOGUE } xxdline(fpo, l, colors, 1); - xxdline(fpo, l, 1); + else xxdline(fpo, l, NULL, 1); } else if (autoskip) - xxdline(fpo, l, -1); /* last chance to flush out suppressed lines */ + xxdline(fpo, l, color ? colors : NULL, -1); /* last chance to flush out suppressed lines */ fclose_or_die(fp, fpo); return 0;
-- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uQoN0-000C2S-KP%40256bit.org.