Mercurial > vim
changeset 33496:33cbd544dc46 v9.0.1998
patch 9.0.1998: xxd: cannot reverse a bit dump
Commit: https://github.com/vim/vim/commit/85f4521808dd9a587c00f9a2927e84217721cfca
Author: tristhaus <tristhaus@yahoo.de>
Date: Fri Oct 6 19:51:13 2023 +0200
patch 9.0.1998: xxd: cannot reverse a bit dump
Problem: xxd: cannot reverse a bit dump
Solution: implement reversing the bit dump using -b -r
closes: #13286
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: tristhaus <tristhaus@yahoo.de>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 06 Oct 2023 20:00:05 +0200 |
parents | 6bf3d26b7ddc |
children | 5bb56da92a88 |
files | runtime/doc/xxd-fr.1 runtime/doc/xxd-fr.UTF-8.1 runtime/doc/xxd-it.1 runtime/doc/xxd-it.UTF-8.1 runtime/doc/xxd-ja.UTF-8.1 runtime/doc/xxd-pl.1 runtime/doc/xxd-pl.UTF-8.1 runtime/doc/xxd-ru.1 runtime/doc/xxd-ru.UTF-8.1 runtime/doc/xxd.1 runtime/doc/xxd.man src/testdir/test_xxd.vim src/version.c src/xxd/xxd.c |
diffstat | 14 files changed, 161 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/runtime/doc/xxd-fr.1 +++ b/runtime/doc/xxd-fr.1 @@ -70,7 +70,7 @@ Convertit en binaires plutt qu'en hexadcimal. Cette option crit les octets comme une squence de "1" et de "0" au lieu d'une conversion en hexadcimal traditionnel. Chaque ligne est prcde par un numro de ligne en hexadcimal et suivie de la reprsentation ASCII (ou -EBCDIC) correspondante. Les options \-r, \-p, \-i ne fonctionnent pas dans ce +EBCDIC) correspondante. Les options \-p, \-i ne fonctionnent pas dans ce mode. .TP .IR "\-c cols " | " \-cols cols"
--- a/runtime/doc/xxd-fr.UTF-8.1 +++ b/runtime/doc/xxd-fr.UTF-8.1 @@ -70,7 +70,7 @@ Convertit en binaires plutôt qu'en hexadécimal. Cette option écrit les octets comme une séquence de "1" et de "0" au lieu d'une conversion en hexadécimal traditionnel. Chaque ligne est précédée par un numéro de ligne en hexadécimal et suivie de la représentation ASCII (ou -EBCDIC) correspondante. Les options \-r, \-p, \-i ne fonctionnent pas dans ce +EBCDIC) correspondante. Les options \-p, \-i ne fonctionnent pas dans ce mode. .TP .IR "\-c cols " | " \-cols cols"
--- a/runtime/doc/xxd-it.1 +++ b/runtime/doc/xxd-it.1 @@ -63,7 +63,7 @@ Richiesta di omissione: Un singolo '*' r Richiesta di un'immagine binaria (cifre binarie), invece che esadecimale. Quest'opzione scrive un byte come otto cifre "1" e "0" invece di usare i numeri esadecimali. Ogni riga preceduta da un indirizzo in esadecimale e -seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-r, \-p, \-i, +seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-p, \-i, specificabili dalla riga comando, non funzionano in questo modo. .TP .IR "\-c colonne " | " \-cols colonne"
--- a/runtime/doc/xxd-it.UTF-8.1 +++ b/runtime/doc/xxd-it.UTF-8.1 @@ -63,7 +63,7 @@ Richiesta di omissione: Un singolo '*' r Richiesta di un'immagine binaria (cifre binarie), invece che esadecimale. Quest'opzione scrive un byte come otto cifre "1" e "0" invece di usare i numeri esadecimali. Ogni riga è preceduta da un indirizzo in esadecimale e -seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-r, \-p, \-i, +seguita da una decodifica ASCII (o EBCDIC). Le opzioni \-p, \-i, specificabili dalla riga comando, non funzionano in questo modo. .TP .IR "\-c colonne " | " \-cols colonne"
--- a/runtime/doc/xxd-ja.UTF-8.1 +++ b/runtime/doc/xxd-ja.UTF-8.1 @@ -58,7 +58,7 @@ 16 進ダンプから元のバイナリに戻すこともできます。 1 オクテットが "1" と "0" の 8 文字で出力されます。 各行の行頭には 16 進数の行番号が表示されます。 行末には ascii (または ebcdic) で表した場合の文字が表示されます。 -このモードでは \-r、\-p、\-i は機能しません。 +このモードでは \-p、\-i は機能しません。 .TP .IR \-e リトルエンディアンの 16 進ダンプに切り替える。
--- a/runtime/doc/xxd-pl.1 +++ b/runtime/doc/xxd-pl.1 @@ -66,7 +66,7 @@ Przecza do zrzutu bitowego (cyfr binarnych) zamiast heksowego. Opcja ta zapisuje oktety jako osiem cyfr 1 lub 0 zamiast normalnego zrzutu heksowego. Kada linia jest poprzedzona przez heksadecymalny numer linii a po nim jego reprezentacj w ascii (lub -ebcdic). Opcje linii polece \-r, \-p, \-i nie dziaaj w tym +ebcdic). Opcje linii polece \-p, \-i nie dziaaj w tym trybie. .TP .IR "\-c cols " | " \-cols cols"
--- a/runtime/doc/xxd-pl.UTF-8.1 +++ b/runtime/doc/xxd-pl.UTF-8.1 @@ -66,7 +66,7 @@ Przełącza do zrzutu bitowego (cyfr binarnych) zamiast heksowego. Opcja ta zapisuje oktety jako osiem cyfr 1 lub 0 zamiast normalnego zrzutu heksowego. Każda linia jest poprzedzona przez heksadecymalny numer linii a po nim jego reprezentacją w ascii (lub -ebcdic). Opcje linii poleceń \-r, \-p, \-i nie działają w tym +ebcdic). Opcje linii poleceń \-p, \-i nie działają w tym trybie. .TP .IR "\-c cols " | " \-cols cols"
--- a/runtime/doc/xxd-ru.1 +++ b/runtime/doc/xxd-ru.1 @@ -70,7 +70,7 @@ xxd , "1" "0". , - ( ascii ebcdic). \-r, \-p, \-i + ( ascii ebcdic). \-p, \-i . .TP .IR "\-c " | " \-cols "
--- a/runtime/doc/xxd-ru.UTF-8.1 +++ b/runtime/doc/xxd-ru.UTF-8.1 @@ -70,7 +70,7 @@ xxd позволяет выполнять декодирование в поток стандартного вывода, При использовании этого ключа вместо обычного шестнадцатеричного представления октетов используются наборы из восьми символов "1" и "0". Каждая строка предваряется номером строки в шестнадцатеричном виде, а завершается символьным -представлением (в виде ascii или ebcdic). Ключи \-r, \-p, \-i в этом режиме +представлением (в виде ascii или ebcdic). Ключи \-p, \-i в этом режиме не работают. .TP .IR "\-c кол " | " \-cols кол"
--- a/runtime/doc/xxd.1 +++ b/runtime/doc/xxd.1 @@ -64,7 +64,7 @@ Switch to bits (binary digits) dump, rat This option writes octets as eight digits "1"s and "0"s instead of a normal hexadecimal dump. Each line is preceded by a line number in hexadecimal and followed by an ASCII (or EBCDIC) representation. The command line switches -\-r, \-p, \-i do not work with this mode. +\-p, \-i do not work with this mode. .TP .IR "\-c cols " | " \-cols cols" Format @@ -133,7 +133,9 @@ it. Use the combination .I \-r \-p to read plain hexadecimal dumps without line number information and without a particular column layout. Additional whitespace and line breaks are allowed -anywhere. +anywhere. Use the combination +.I \-r \-b +to read a bits dump instead of a hex dump. .TP .IR \-R " " when In output the hex-value and the value are both colored with the same color
--- a/runtime/doc/xxd.man +++ b/runtime/doc/xxd.man @@ -37,7 +37,7 @@ OPTIONS option writes octets as eight digits "1"s and "0"s instead of a normal hexadecimal dump. Each line is preceded by a line number in hexadecimal and followed by an ASCII (or EBCDIC) representa‐ - tion. The command line switches -r, -p, -i do not work with this + tion. The command line switches -p, -i do not work with this mode. -c cols | -cols cols @@ -97,7 +97,8 @@ OPTIONS truncating it. Use the combination -r -p to read plain hexadeci‐ mal dumps without line number information and without a particu‐ lar column layout. Additional whitespace and line breaks are al‐ - lowed anywhere. + lowed anywhere. Use the combination -r -b to read a bits dump + instead of a hex dump. -R when In output the hex-value and the value are both colored with the
--- a/src/testdir/test_xxd.vim +++ b/src/testdir/test_xxd.vim @@ -312,6 +312,31 @@ func Test_xxd_patch() call delete('Xxxdout') endfunc +func Test_xxd_patch_with_bitdump() + let cmd1 = 'silent !' .. s:xxd_cmd .. ' -r -b Xxxdin Xxxdfile' + let cmd2 = 'silent !' .. s:xxd_cmd .. ' -g1 Xxxdfile > Xxxdout' + + call writefile(["2: 01000001 01000001", "8: 01000010 01000010"], 'Xxxdin', 'D') + call writefile(['::::::::'], 'Xxxdfile', 'D') + exe cmd1 + exe cmd2 + call assert_equal(['00000000: 3a 3a 41 41 3a 3a 3a 3a 42 42 ::AA::::BB'], readfile('Xxxdout')) + + call writefile(["1: 01000011 01000011", "4: 01000100 01000100"], 'Xxxdin', 'D') + call writefile(['::::::::'], 'Xxxdfile', 'D') + exe cmd1 + exe cmd2 + call assert_equal(['00000000: 3a 43 43 3a 44 44 3a 3a 0a :CC:DD::.'], readfile('Xxxdout')) + + call writefile(["02: 01000101 01000101", "08: 01000110 01000110"], 'Xxxdin', 'D') + call writefile(['::::::::'], 'Xxxdfile', 'D') + exe cmd1 + exe cmd2 + call assert_equal(['00000000: 3a 3a 45 45 3a 3a 3a 3a 46 46 ::EE::::FF'], readfile('Xxxdout')) + + call delete('Xxxdout') +endfunc + " Various ways with wrong arguments that trigger the usage output. func Test_xxd_usage() for arg in ['-h', '-c', '-g', '-o', '-s', '-l', '-X', '-R', 'one two three'] @@ -336,6 +361,18 @@ func Test_xxd_bit_dump() bwipe! endfunc +func Test_xxd_revert_bit_dump() + new + exe 'r! printf "00000000: 01000001 01100010 01000011 01100100 01000101 01100110 01000111 01101000 AbCdEfGh" | ' . s:xxd_cmd . ' -r -b1 -c 8' + call assert_match('AbCdEfGh', join(getline(1, 3))) + bwipe! + + new + exe 'r! printf "00000000: 01000001 01100010 01000011 01100100 01000101 01100110 AbCdEf\n00000006: 01000111 01101000 Gh\n" | ' . s:xxd_cmd . ' -r -b1' + call assert_match('AbCdEfGh', join(getline(1, 3))) + bwipe! +endfunc + func Test_xxd_version() new exe 'r! ' . s:xxd_cmd . ' -v'
--- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1998, +/**/ 1997, /**/ 1996,
--- a/src/xxd/xxd.c +++ b/src/xxd/xxd.c @@ -57,6 +57,7 @@ * 14.01.2022 Disable extra newlines with -c0 -p by Erik Auerswald. * 20.06.2022 Permit setting the variable names used by -i by David Gow * 31.08.2023 -R never/auto/always prints colored output + * 06.10.2023 enable -r -b to reverse bit dumps * * (c) 1990-1998 by Juergen Weigert (jnweiger@gmail.com) * @@ -135,7 +136,7 @@ extern void perror __P((char *)); # endif #endif -char version[] = "xxd 2023-09-04 by Juergen Weigert et al."; +char version[] = "xxd 2023-10-06 by Juergen Weigert et al."; #ifdef WIN32 char osver[] = " (Win32)"; #else @@ -234,7 +235,7 @@ exit_with_usage(void) fprintf(stderr, " or\n %s -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]\n", pname); fprintf(stderr, "Options:\n"); fprintf(stderr, " -a toggle autoskip: A single '*' replaces nul-lines. Default off.\n"); - fprintf(stderr, " -b binary digit dump (incompatible with -ps,-i,-r). Default hex.\n"); + fprintf(stderr, " -b binary digit dump (incompatible with -ps,-i). Default hex.\n"); fprintf(stderr, " -C capitalize variable names in C include file style (-i).\n"); fprintf(stderr, " -c cols format <cols> octets per line. Default 16 (-i: 12, -ps: 30).\n"); fprintf(stderr, " -E show characters in EBCDIC. Default ASCII.\n"); @@ -325,6 +326,17 @@ parse_hex_digit(int c) } /* + * If "c" is a bin digit, return the value. + * Otherwise return -1. + */ + static int +parse_bin_digit(int c) +{ + return (c >= '0' && c <= '1') ? c - '0' + : -1; +} + +/* * Ignore text on "fpi" until end-of-line or end-of-file. * Return the '\n' or EOF character. * When an error is encountered exit with an error message. @@ -352,7 +364,7 @@ huntype( int hextype, long base_off) { - int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols; + int c, ign_garb = 1, n1 = -1, n2 = 0, n3, p = cols, bt, b = 0, bcnt = 0; long have_off = 0, want_off = 0; rewind(fpi); @@ -368,25 +380,60 @@ huntype( if (hextype == HEX_POSTSCRIPT && (c == ' ' || c == '\n' || c == '\t')) continue; - n3 = n2; - n2 = n1; + if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT) + { + n3 = n2; + n2 = n1; - n1 = parse_hex_digit(c); - if (n1 == -1 && ign_garb) - continue; + n1 = parse_hex_digit(c); + if (n1 == -1 && ign_garb) + continue; + } + else /* HEX_BITS */ + { + n1 = parse_hex_digit(c); + if (n1 == -1 && ign_garb) + continue; + + bt = parse_bin_digit(c); + if (bt != -1) + { + b = ((b << 1) | bt); + ++bcnt; + } + } ign_garb = 0; - if (!hextype && (p >= cols)) + if ((hextype != HEX_POSTSCRIPT) && (p >= cols)) { - if (n1 < 0) - { - p = 0; - continue; - } - want_off = (want_off << 4) | n1; - continue; - } + if (hextype == HEX_NORMAL) + { + if (n1 < 0) + { + p = 0; + continue; + } + want_off = (want_off << 4) | n1; + } + else /* HEX_BITS */ + { + n1 = parse_hex_digit(c); + if (n1 >= 0) + { + want_off = (want_off << 4) | n1; + } + + if (bt < 0) + { + p = 0; + bcnt = 0; + b = 0; + continue; + } + } + continue; + } if (base_off + want_off != have_off) { @@ -402,23 +449,40 @@ huntype( putc_or_die(0, fpo); } - if (n2 >= 0 && n1 >= 0) - { - putc_or_die((n2 << 4) | n1, fpo); - have_off++; - want_off++; - n1 = -1; - if (!hextype && (++p >= cols)) - /* skip the rest of the line as garbage */ - c = skip_to_eol(fpi, c); - } - else if (n1 < 0 && n2 < 0 && n3 < 0) - /* already stumbled into garbage, skip line, wait and see */ - c = skip_to_eol(fpi, c); + if (hextype == HEX_NORMAL || hextype == HEX_POSTSCRIPT) + { + if (n2 >= 0 && n1 >= 0) + { + putc_or_die((n2 << 4) | n1, fpo); + have_off++; + want_off++; + n1 = -1; + if (!hextype && (++p >= cols)) + /* skip the rest of the line as garbage */ + c = skip_to_eol(fpi, c); + } + else if (n1 < 0 && n2 < 0 && n3 < 0) + /* already stumbled into garbage, skip line, wait and see */ + c = skip_to_eol(fpi, c); + } + else /* HEX_BITS */ + { + if (bcnt == 8) + { + putc_or_die(b, fpo); + have_off++; + want_off++; + b = 0; + bcnt = 0; + if (++p >= cols) + /* skip the rest of the line as garbage */ + c = skip_to_eol(fpi, c); + } + } if (c == '\n') { - if (!hextype) + if (hextype == HEX_NORMAL || hextype == HEX_BITS) want_off = 0; p = cols; ign_garb = 1; @@ -847,12 +911,17 @@ main(int argc, char *argv[]) } if (revert) - { - if (hextype && (hextype != HEX_POSTSCRIPT)) - error_exit(-1, "Sorry, cannot revert this type of hexdump"); - return huntype(fp, fpo, cols, hextype, - negseek ? -seekoff : seekoff); - } + switch (hextype) + { + case HEX_NORMAL: + case HEX_POSTSCRIPT: + case HEX_BITS: + return huntype(fp, fpo, cols, hextype, + negseek ? -seekoff : seekoff); + break; + default: + error_exit(-1, "Sorry, cannot revert this type of hexdump"); + } if (seekoff || negseek || !relseek) {