nxxd 1.0 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +45 -1
- data/bin/nxxd +17 -15
- data/lib/nxxd/nvim.rb +107 -57
- data/lib/nxxd/version.rb +1 -1
- data/lib/nxxd.rb +26 -20
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68a908962e81a416580c2987b7523f755e85e1963c20908420fb579710b6a865
|
4
|
+
data.tar.gz: b18d9db546926037e9646a22e6c8394fd6d4ff86ad048b8be22a697d07698a87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d941c8d1202b8bcbf0b1b0507216665e1c1e81035ff224861e6183d8a82b4354b701a3231e14803c9e7d934dc75cbb1dd8d6210ca46c36f8275c3234d34a25af
|
7
|
+
data.tar.gz: abd20b6a161993d5ab0d8047623c8d137b7eec56512f72269a942feae25521ecd9549faceec3276e4df654008a84dcdf4c37b1c000ef5e473a74251850307380
|
data/README.md
CHANGED
@@ -65,11 +65,16 @@ Here's an example:
|
|
65
65
|
|
66
66
|
```ruby
|
67
67
|
require "nxxd"
|
68
|
-
|
69
68
|
data = " !\"\#$%&'()*+,-./0123456789:;<=>?"
|
70
69
|
Nxxd::Dump.new.run data do |l| puts l end
|
71
70
|
```
|
72
71
|
|
72
|
+
Or just:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
puts Nxxd::Dump.new.run data
|
76
|
+
```
|
77
|
+
|
73
78
|
Reverse operation allows free address jumping.
|
74
79
|
Both string and file output can be done.
|
75
80
|
|
@@ -90,6 +95,45 @@ end
|
|
90
95
|
```
|
91
96
|
|
92
97
|
|
98
|
+
## Inside Neovim
|
99
|
+
|
100
|
+
If you're using Neovim and the Ruby provider
|
101
|
+
[ruby-nvim](https://github.com/BertramScharpf/ruby-nvim) (Not the official
|
102
|
+
neovim-ruby!), you probably prefer to pipe from and to buffers.
|
103
|
+
|
104
|
+
```vim
|
105
|
+
rubyfile <nxxd/nvim>
|
106
|
+
vertical HexDump /etc/localtime
|
107
|
+
```
|
108
|
+
|
109
|
+
In case you have a string in a Ruby variable, dump it like this:
|
110
|
+
|
111
|
+
```vim
|
112
|
+
ruby t = "tränenüberströmt"
|
113
|
+
ruby Nxxd::Nvim.dump_data t
|
114
|
+
```
|
115
|
+
|
116
|
+
You may dump a programs output as well:
|
117
|
+
|
118
|
+
```vim
|
119
|
+
HexDump! echo QmF6aW5nYSEK | openssl enc -a -d
|
120
|
+
HexDump! dd if=/dev/urandom bs=16 count=4
|
121
|
+
```
|
122
|
+
|
123
|
+
Pipe your editor lines to a program like this:
|
124
|
+
|
125
|
+
```
|
126
|
+
1 H4sIALDvomcAA7u3
|
127
|
+
2 dt/7ewOIAX8tU5eA
|
128
|
+
3 AAAA
|
129
|
+
~
|
130
|
+
~
|
131
|
+
:1,3HexPipe openssl enc -a -d | gzip -cd
|
132
|
+
```
|
133
|
+
|
134
|
+
See the file [nxxd.txt](./vim/doc/nxxd.txt) for a full documentation.
|
135
|
+
|
136
|
+
|
93
137
|
## Colorization
|
94
138
|
|
95
139
|
There is no and there will be no color support. Pipe the output to your
|
data/bin/nxxd
CHANGED
@@ -15,26 +15,28 @@ module Nxxd
|
|
15
15
|
NAME = "nxxd"
|
16
16
|
|
17
17
|
OPTIONS = {
|
18
|
-
"r" => [ :reverse,
|
19
|
-
"o" => [ :output,
|
18
|
+
"r" => [ :reverse, true, "Reverse operation, pack"],
|
19
|
+
"o" => [ :output, :NAME, "Output file (- = stdout)"],
|
20
20
|
"output" => "o",
|
21
|
-
"f" => [ :full,
|
21
|
+
"f" => [ :full, true, "Full output (no squeeze)"],
|
22
22
|
"full" => "f",
|
23
|
-
"a" => [ :full,
|
24
|
-
"p" => [ :plain,
|
25
|
-
"u" => [ :upper,
|
23
|
+
"a" => [ :full, false, "Abbreviate (squeeze duplicate lines)"],
|
24
|
+
"p" => [ :plain, true, "Plain output (no comments, no C variables)"],
|
25
|
+
"u" => [ :upper, true, "Upper case A-F"],
|
26
26
|
"upper" => "u",
|
27
|
-
"l" => [ :line_size,
|
27
|
+
"l" => [ :line_size, :NUM, "Line size"],
|
28
28
|
"line" => "l",
|
29
|
-
"d" => [ :addr_len,
|
29
|
+
"d" => [ :addr_len, :NUM, "Address length"],
|
30
30
|
"addrs" => "d",
|
31
|
-
"i" => [ :cnums,
|
31
|
+
"i" => [ :cnums, true, "C-style number literals"],
|
32
32
|
"include" => "i",
|
33
|
-
"C" => [ :capitals,
|
33
|
+
"C" => [ :capitals, true, "Capitalize C variable names with -i"],
|
34
34
|
"capitalize" => "C",
|
35
|
-
"
|
35
|
+
"c" => [ :consecutive, true, "Consecutive undump (ignore addresses)"],
|
36
|
+
"consecutive" => "c",
|
37
|
+
"h" => [ :help, :help, "Print this help message"],
|
36
38
|
"help" => "h",
|
37
|
-
"v" => [ :version,
|
39
|
+
"v" => [ :version, :version, "Version information"],
|
38
40
|
"version" => "v",
|
39
41
|
}
|
40
42
|
|
@@ -154,9 +156,9 @@ module Nxxd
|
|
154
156
|
|
155
157
|
def run
|
156
158
|
open_output do |o|
|
157
|
-
if @opts
|
159
|
+
if @opts.delete :reverse then
|
158
160
|
open_inputs do |f|
|
159
|
-
Dump.reverse f, o
|
161
|
+
Dump.reverse f, o, **@opts
|
160
162
|
end
|
161
163
|
else
|
162
164
|
cls = (@opts.delete :cnums) ? DumpNums : Dump
|
@@ -188,8 +190,8 @@ module Nxxd
|
|
188
190
|
plain = @opts.delete :plain
|
189
191
|
@inputs.each do |i|
|
190
192
|
i = nil if i == "-"
|
191
|
-
@opts[ :input] = i unless plain
|
192
193
|
if i then
|
194
|
+
@opts[ :input] = i unless plain or @opts[ :reverse]
|
193
195
|
File.open i, "r" do |f|
|
194
196
|
yield f
|
195
197
|
end
|
data/lib/nxxd/nvim.rb
CHANGED
@@ -8,35 +8,12 @@ require "nxxd"
|
|
8
8
|
raise "This file must be required from inside Neovim using the 'nvim' Rubygem."
|
9
9
|
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
module Kernel
|
19
|
-
class <<self
|
20
|
-
def popen_outerr a
|
21
|
-
ro, wo = IO.pipe
|
22
|
-
re, we = IO.pipe
|
23
|
-
fork do
|
24
|
-
ro.close
|
25
|
-
re.close
|
26
|
-
STDOUT.reopen wo
|
27
|
-
STDERR.reopen we
|
28
|
-
exec a
|
29
|
-
end
|
30
|
-
wo.close
|
31
|
-
we.close
|
32
|
-
yield ro, re
|
33
|
-
Process.waitpid
|
34
|
-
ensure
|
35
|
-
ro.close
|
36
|
-
re.close
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
11
|
+
<<~'EOT'.each_line { |c| c.chomp! ; $vim.command c }
|
12
|
+
command -nargs=? -bang -complete=file HexDump ruby Nxxd::Nvim.dump<bang> <q-args>, <q-mods>
|
13
|
+
command -nargs=1 -range=% -complete=file HexPipe ruby Nxxd::Nvim.pipe <q-args>, <q-mods>, <line1>..<line2>
|
14
|
+
command -nargs=? -range=% -bang -complete=file -bar HexPack ruby Nxxd::Nvim.pack<bang> <q-args>, <range>, <line1>..<line2>
|
15
|
+
command -nargs=1 -range=% -complete=file HexFeed ruby Nxxd::Nvim.feed <q-args>, <line1>..<line2>
|
16
|
+
EOT
|
40
17
|
|
41
18
|
|
42
19
|
module Nxxd
|
@@ -45,69 +22,142 @@ module Nxxd
|
|
45
22
|
|
46
23
|
class <<self
|
47
24
|
|
48
|
-
|
49
|
-
|
25
|
+
attr_accessor :split
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def split_new mods
|
30
|
+
if mods.notempty? then
|
31
|
+
"#{mods} new"
|
32
|
+
else
|
33
|
+
case @split
|
34
|
+
when /\bvert/ then "vnew"
|
35
|
+
when /\bhor/ then "new"
|
36
|
+
else "enew"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
public
|
42
|
+
|
43
|
+
def dump a, m
|
44
|
+
a = a.notempty?
|
45
|
+
a ||= cur_buf_name
|
50
46
|
File.open a do |f|
|
51
|
-
|
47
|
+
dump_data f, a, m
|
52
48
|
end
|
53
49
|
$vim.get_current_buf.set_var "origfile", a
|
54
50
|
end
|
55
51
|
|
56
|
-
def dump! a
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
def dump! a, m
|
53
|
+
a = a.notempty?
|
54
|
+
a ||= cur_buf_name_exec
|
55
|
+
pipe a, m, nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def pipe a, m, range
|
59
|
+
popen a do |ro,re|
|
60
|
+
begin
|
61
|
+
if range then
|
62
|
+
# It would be nicer to write the lines as they are demanded. If
|
63
|
+
# you have an idea how this could easily be done, feel free to
|
64
|
+
# propose a patch. Putting this begin-end block into a Thread
|
65
|
+
# didn't work.
|
66
|
+
(Neovim::Lines.new $vim.get_current_buf, range).each { |l| ro.puts l }
|
67
|
+
end
|
68
|
+
ro.close_write
|
69
|
+
end
|
70
|
+
dump_data ro, a, m
|
71
|
+
re.each_line { |l|
|
72
|
+
l.chomp!
|
73
|
+
$vim.put [ "# #{l}"], "l", false, true
|
74
|
+
}
|
61
75
|
end
|
62
76
|
$?.success? or $vim.put [ "### Exit code: #{$?.exitstatus}"], "l", false, true
|
63
77
|
end
|
64
78
|
|
65
|
-
|
66
|
-
|
67
|
-
def dump_file a, f
|
68
|
-
$vim.command "enew"
|
79
|
+
def dump_data f, a = nil, m = nil
|
80
|
+
(split_new m).tap { |sc| $vim.command sc }
|
69
81
|
$vim.set_option filetype: "xxd", buftype: "nofile"
|
70
82
|
$vim.get_current_buf.set_name "[hex: #{a}]"
|
71
83
|
(Dump.new input: a).run f do |l|
|
72
|
-
$vim.put [l], "l", false, true
|
84
|
+
$vim.put [ l], "l", false, true
|
73
85
|
end
|
74
86
|
end
|
75
87
|
|
88
|
+
private
|
89
|
+
|
90
|
+
def cur_buf_name
|
91
|
+
# $vim.buf_get_name 0 # gives the full path
|
92
|
+
$vim.evaluate "bufname('%')"
|
93
|
+
end
|
94
|
+
|
95
|
+
def cur_buf_name_exec
|
96
|
+
r = cur_buf_name
|
97
|
+
r = File.join ".", r unless r.include? "/"
|
98
|
+
r
|
99
|
+
end
|
100
|
+
|
101
|
+
def popen cmd
|
102
|
+
re, we = IO.pipe
|
103
|
+
IO.popen cmd, "r+", err: we do |ro|
|
104
|
+
we.close
|
105
|
+
yield ro, re
|
106
|
+
end
|
107
|
+
ensure
|
108
|
+
re.close
|
109
|
+
end
|
110
|
+
|
76
111
|
public
|
77
112
|
|
78
|
-
def pack a, range
|
79
|
-
pack_check a, range do |d|
|
113
|
+
def pack a, rarg, range
|
114
|
+
pack_check a, rarg, range do |d|
|
80
115
|
raise "File exists. Overwrite with '!'." if File.exist? d
|
81
116
|
end
|
82
117
|
end
|
83
118
|
|
84
|
-
def pack! a, range
|
85
|
-
pack_check a, range do || end
|
119
|
+
def pack! a, rarg, range
|
120
|
+
pack_check a, rarg, range do || end
|
86
121
|
end
|
87
122
|
|
88
123
|
private
|
89
124
|
|
90
|
-
def pack_check a, range
|
125
|
+
def pack_check a, rarg, range
|
91
126
|
b = $vim.get_current_buf
|
92
127
|
a = a.notempty?
|
93
|
-
a
|
94
|
-
|
128
|
+
unless a then
|
129
|
+
a = b.get_var "origfile" rescue nil
|
130
|
+
a or raise "No file name given."
|
131
|
+
rarg.zero? or raise "No range allowed when using default output name."
|
132
|
+
end
|
95
133
|
yield a
|
96
134
|
File.open a, "w" do |f|
|
97
|
-
r =
|
135
|
+
r = Neovim::Lines.new b, range
|
98
136
|
Nxxd::Dump.reverse r, f
|
99
137
|
end
|
100
138
|
end
|
101
139
|
|
102
|
-
|
140
|
+
public
|
103
141
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
142
|
+
def feed a, range
|
143
|
+
popen a do |ro,re|
|
144
|
+
r = Neovim::Lines.new $vim.get_current_buf, range
|
145
|
+
Nxxd::Dump.reverse r, ro, consecutive: true
|
146
|
+
ro.close_write
|
147
|
+
$vim.command "#{range.last}"
|
148
|
+
$vim.put [ ""], "l", true, true
|
149
|
+
ro.each_line { |l|
|
150
|
+
l.chomp!
|
151
|
+
$vim.put [ l], "l", false, true
|
152
|
+
}
|
153
|
+
re.each_line { |l|
|
154
|
+
l.chomp!
|
155
|
+
$vim.put [ "# #{l}"], "l", false, true
|
156
|
+
}
|
157
|
+
end
|
158
|
+
$?.success? or $vim.put [ "### Exit code: #{$?.exitstatus}"], "l", false, true
|
110
159
|
end
|
160
|
+
|
111
161
|
end
|
112
162
|
|
113
163
|
end
|
data/lib/nxxd/version.rb
CHANGED
data/lib/nxxd.rb
CHANGED
@@ -15,6 +15,7 @@ module Nxxd
|
|
15
15
|
i = 0
|
16
16
|
while i < input.bytesize do
|
17
17
|
b = input.byteslice i, @line_size
|
18
|
+
b.force_encoding Encoding::ASCII_8BIT # Ruby, shouldn't this rather be self-evident?
|
18
19
|
yield b
|
19
20
|
i += @line_size
|
20
21
|
end
|
@@ -50,6 +51,7 @@ module Nxxd
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def run input
|
54
|
+
block_given? or return [].tap { |r| run input do |l| r.push l end }
|
53
55
|
addr = 0
|
54
56
|
prev, repeat = nil, false
|
55
57
|
yield "# #@input" if @input
|
@@ -83,7 +85,7 @@ module Nxxd
|
|
83
85
|
|
84
86
|
class <<self
|
85
87
|
|
86
|
-
def reverse input, output = nil
|
88
|
+
def reverse input, output = nil, consecutive: nil
|
87
89
|
output ||= ""
|
88
90
|
o = String === output ? (WriteChunksString.new output) : output
|
89
91
|
o.set_encoding Encoding::ASCII_8BIT
|
@@ -91,27 +93,30 @@ module Nxxd
|
|
91
93
|
input.each_line { |l|
|
92
94
|
l.chomp!
|
93
95
|
case l
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
96
|
+
when /^\s*(?:#|$)/ then
|
97
|
+
nil
|
98
|
+
when /^\*/ then
|
99
|
+
consecutive and
|
100
|
+
raise "Addressless undump doesn't allow repeat specifications."
|
101
|
+
repeat = true
|
102
|
+
when /^(?:(\h+):)?\s*((?:\h\h ?)*)/ then
|
103
|
+
addr, nibs = $~.captures
|
104
|
+
if !consecutive && addr then
|
105
|
+
addr = $1.to_i 0x10
|
106
|
+
if repeat then
|
107
|
+
loop do
|
108
|
+
s = addr - o.tell
|
109
|
+
break if s <= 0
|
110
|
+
o.write s >= r.length ? r : r[ 0, s]
|
108
111
|
end
|
109
|
-
|
112
|
+
repeat = false
|
110
113
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
114
|
+
o.seek addr
|
115
|
+
end
|
116
|
+
r = (nibs.scan /\h\h/).map { |x| x.to_i 0x10 }.pack "C*"
|
117
|
+
o.write r
|
118
|
+
else
|
119
|
+
raise "Uninterpretable hex dump: #{l.chomp}"
|
115
120
|
end
|
116
121
|
}
|
117
122
|
output
|
@@ -140,6 +145,7 @@ module Nxxd
|
|
140
145
|
end
|
141
146
|
|
142
147
|
def run input, &block
|
148
|
+
block_given? or return [].tap { |r| run input do |l| r.push l end }
|
143
149
|
if @varname then
|
144
150
|
yield "unsigned char #@varname[] = {"
|
145
151
|
len = run_plain input, &block
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nxxd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.1'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bertram Scharpf
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-02-05 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: 'Yet another Xxd reimplementation.
|
13
13
|
|
@@ -45,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
45
|
version: '0'
|
46
46
|
requirements:
|
47
47
|
- Just Ruby
|
48
|
-
rubygems_version: 3.6.
|
48
|
+
rubygems_version: 3.6.3
|
49
49
|
specification_version: 4
|
50
50
|
summary: Hex Dump Tool
|
51
51
|
test_files: []
|