nxxd 1.0 → 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|