147 lines
3.8 KiB
V
147 lines
3.8 KiB
V
module main
|
|
|
|
import os
|
|
import flag
|
|
import strings
|
|
|
|
const (
|
|
tool_version = '0.0.4'
|
|
tool_description = 'Converts a list of arbitrary files into a single v module file.'
|
|
)
|
|
|
|
struct Context {
|
|
mut:
|
|
files []string
|
|
prefix string
|
|
show_help bool
|
|
module_name string
|
|
write_file string
|
|
}
|
|
|
|
fn (context Context) header() string {
|
|
mut header_s := ''
|
|
header_s += 'module $context.module_name\n'
|
|
header_s += '\n'
|
|
allfiles := context.files.join(' ')
|
|
mut options := []string{}
|
|
if context.prefix.len > 0 {
|
|
options << '-p $context.prefix'
|
|
}
|
|
if context.module_name.len > 0 {
|
|
options << '-m $context.module_name'
|
|
}
|
|
if context.write_file.len > 0 {
|
|
options << '-w $context.write_file'
|
|
}
|
|
soptions := options.join(' ')
|
|
header_s += '// File generated by:\n'
|
|
header_s += '// v bin2v $allfiles $soptions\n'
|
|
header_s += '// Please, do not edit this file.\n'
|
|
header_s += '// Your changes may be overwritten.\n'
|
|
header_s += 'const (\n'
|
|
return header_s
|
|
}
|
|
|
|
fn (context Context) footer() string {
|
|
return ')\n'
|
|
}
|
|
|
|
fn (context Context) file2v(bname string, fbytes []byte, bn_max int) string {
|
|
mut sb := strings.new_builder(1000)
|
|
bn_diff_len := bn_max - bname.len
|
|
sb.write_string('\t${bname}_len' + ' '.repeat(bn_diff_len - 4) + ' = $fbytes.len\n')
|
|
fbyte := fbytes[0]
|
|
bnmae_line := '\t$bname' + ' '.repeat(bn_diff_len) + ' = [byte($fbyte), '
|
|
sb.write_string(bnmae_line)
|
|
mut line_len := bnmae_line.len + 3
|
|
for i := 1; i < fbytes.len; i++ {
|
|
b := int(fbytes[i]).str()
|
|
if line_len > 94 {
|
|
sb.go_back(1)
|
|
sb.write_string('\n\t\t')
|
|
line_len = 8
|
|
}
|
|
if i == fbytes.len - 1 {
|
|
sb.write_string(b)
|
|
line_len += b.len
|
|
} else {
|
|
sb.write_string('$b, ')
|
|
line_len += b.len + 2
|
|
}
|
|
}
|
|
sb.write_string(']!\n')
|
|
return sb.str()
|
|
}
|
|
|
|
fn (context Context) bname_and_bytes(file string) ?(string, []byte) {
|
|
fname := os.file_name(file)
|
|
fname_escaped := fname.replace_each(['.', '_', '-', '_'])
|
|
byte_name := '$context.prefix$fname_escaped'.to_lower()
|
|
fbytes := os.read_bytes(file) or { return error('Error: $err.msg') }
|
|
return byte_name, fbytes
|
|
}
|
|
|
|
fn (context Context) max_bname_len(bnames []string) int {
|
|
mut max := 0
|
|
for n in bnames {
|
|
if n.len > max {
|
|
max = n.len
|
|
}
|
|
}
|
|
// Add 4 to max due to "_len" suffix
|
|
return max + 4
|
|
}
|
|
|
|
fn main() {
|
|
mut context := Context{}
|
|
mut fp := flag.new_flag_parser(os.args[1..])
|
|
fp.application('v bin2v')
|
|
fp.version(tool_version)
|
|
fp.description(tool_description)
|
|
fp.arguments_description('FILE [FILE]...')
|
|
context.show_help = fp.bool('help', `h`, false, 'Show this help screen.')
|
|
context.module_name = fp.string('module', `m`, 'binary', 'Name of the generated module.')
|
|
context.prefix = fp.string('prefix', `p`, '', 'A prefix put before each resource name.')
|
|
context.write_file = fp.string('write', `w`, '', 'Write directly to a file with the given name.')
|
|
if context.show_help {
|
|
println(fp.usage())
|
|
exit(0)
|
|
}
|
|
files := fp.finalize() or {
|
|
eprintln('Error: $err.msg')
|
|
exit(1)
|
|
}
|
|
real_files := files.filter(it != 'bin2v')
|
|
if real_files.len == 0 {
|
|
println(fp.usage())
|
|
exit(0)
|
|
}
|
|
context.files = real_files
|
|
if context.write_file != '' && os.file_ext(context.write_file) !in ['.vv', '.v'] {
|
|
context.write_file += '.v'
|
|
}
|
|
mut file_byte_map := map[string][]byte{}
|
|
for file in real_files {
|
|
bname, fbytes := context.bname_and_bytes(file) or {
|
|
eprintln(err.msg)
|
|
exit(1)
|
|
}
|
|
file_byte_map[bname] = fbytes
|
|
}
|
|
max_bname := context.max_bname_len(file_byte_map.keys())
|
|
if context.write_file.len > 0 {
|
|
mut out_file := os.create(context.write_file) ?
|
|
out_file.write_string(context.header()) ?
|
|
for bname, fbytes in file_byte_map {
|
|
out_file.write_string(context.file2v(bname, fbytes, max_bname)) ?
|
|
}
|
|
out_file.write_string(context.footer()) ?
|
|
} else {
|
|
print(context.header())
|
|
for bname, fbytes in file_byte_map {
|
|
print(context.file2v(bname, fbytes, max_bname))
|
|
}
|
|
print(context.footer())
|
|
}
|
|
}
|