Skip to content

Instantly share code, notes, and snippets.

@166MMX
Forked from GreyCat/c-struct-to-ksy.rb
Last active May 15, 2021 22:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 166MMX/770fe408f80b2d5a176d2e526907b8f3 to your computer and use it in GitHub Desktop.
Save 166MMX/770fe408f80b2d5a176d2e526907b8f3 to your computer and use it in GitHub Desktop.
Convert C struct into Kaitai Struct spec (.ksy)
#!/usr/bin/env ruby
require 'yaml'
TYPE_TO_KSY = {
'uint8_t' => 'u1',
'uint16_t' => 'u2',
'uint32_t' => 'u4',
'uint64_t' => 'u8',
'int8_t' => 's1',
'int16_t' => 's2',
'int32_t' => 's4',
'int64_t' => 's8',
'char' => 's1',
'short' => 's2',
'int' => 's4',
'uint' => 'u4',
'long' => 's8',
'float' => 'f4',
'double' => 'f8',
'WORD' => 'u2',
'DWORD' => 'u4',
'__s32' => 's4',
'__s64' => 's8',
'off_t' => 'u8', # __int64_t
}
def parse_body(body)
s = []
body.gsub(/\s*(?<type>(?:[A-Za-z0-9_]+|(?:(?:un)?signed\s+)?(?:char|(?:(?:short|(?:long\s+)?long)\s+)?(int))?|(?:float|(?:long\s+)?double)))\s+(?<pointer>\*)*(?<name>[A-Za-z0-9_]+)(?:\s*\[(?<array>[0-9]+)\])?(?:\s*:\s*(?<bit>[0-8]))?\s*;(\s*\/\*\s*(?<comment_body>.*?)\s*\*\/)?/) {
type, pointer, name, array, bit, comment, comment_body = $1, $2, $3, $4, $5, $6, $7
h = {'id' => name, 'type' => TYPE_TO_KSY[type] || type}
if pointer and type == 'char' and array
h['type'] = 'str'
h['encoding'] = 'ASCII'
h['size'] = array.to_i
end
if bit
h['type'] = 'b' + bit
end
if array and type != 'char'
h['repeat'] = 'expr'
h['repeat-expr'] = array.to_i
end
h['doc'] = comment_body unless comment_body.nil? or comment_body.empty?
s << h
}
s
r = {'seq' => s}
end
r = {}
$stdin.read.gsub(/struct\s+([A-Za-z0-9_]+)?\s*\{(.*?)\}\s*(?:[A-Z_]+\s*)?(\w*?);/m) {
tag, body, name = $1, $2, $3
name = name.split(/\s*,\s*/)[0]
name = tag if name.nil? or name.empty?
r[name] = parse_body(body)
}
puts({'types' => r}.to_yaml)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment