diff options
Diffstat (limited to 'node_modules/ctype/ctf.js')
-rw-r--r-- | node_modules/ctype/ctf.js | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/node_modules/ctype/ctf.js b/node_modules/ctype/ctf.js new file mode 100644 index 000000000..66d5f7352 --- /dev/null +++ b/node_modules/ctype/ctf.js @@ -0,0 +1,245 @@ +/* + * ctf.js + * + * Understand and parse all of the different JSON formats of CTF data and + * translate that into a series of node-ctype friendly pieces. The reason for + * the abstraction is to handle different changes in the file format. + * + * We have to be careful here that we don't end up using a name that is already + * a built in type. + */ +var mod_assert = require('assert'); +var ASSERT = mod_assert.ok; + +var ctf_versions = [ '1.0' ]; +var ctf_entries = [ 'integer', 'float', 'typedef', 'struct' ]; +var ctf_deftypes = [ 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', + 'uint32_t', 'float', 'double' ]; + +function ctfParseInteger(entry, ctype) +{ + var name, sign, len, type; + + name = entry['name']; + if (!('signed' in entry['integer'])) + throw (new Error('Malformed CTF JSON: integer missing ' + + 'signed value')); + + + if (!('length' in entry['integer'])) + throw (new Error('Malformed CTF JSON: integer missing ' + + 'length value')); + + sign = entry['integer']['signed']; + len = entry['integer']['length']; + type = null; + + if (sign && len == 1) + type = 'int8_t'; + else if (len == 1) + type = 'uint8_t'; + else if (sign && len == 2) + type = 'int16_t'; + else if (len == 2) + type = 'uint16_t'; + else if (sign && len == 4) + type = 'int32_t'; + else if (len == 4) + type = 'uint32_t'; + else if (sign && len == 8) + type = 'int64_t'; + else if (len == 8) + type = 'uint64_t'; + + if (type === null) + throw (new Error('Malformed CTF JSON: integer has ' + + 'unsupported length and sign - ' + len + '/' + sign)); + + /* + * This means that this is the same as one of our built in types. If + * that's the case defining it would be an error. So instead of trying + * to typedef it, we'll return here. + */ + if (name == type) + return; + + if (name == 'char') { + ASSERT(type == 'int8_t'); + return; + } + + ctype.typedef(name, type); +} + +function ctfParseFloat(entry, ctype) +{ + var name, len; + + name = entry['name']; + if (!('length' in entry['float'])) + throw (new Error('Malformed CTF JSON: float missing ' + + 'length value')); + + len = entry['float']['length']; + if (len != 4 && len != 8) + throw (new Error('Malformed CTF JSON: float has invalid ' + + 'length value')); + + if (len == 4) { + if (name == 'float') + return; + ctype.typedef(name, 'float'); + } else if (len == 8) { + if (name == 'double') + return; + ctype.typedef(name, 'double'); + } +} + +function ctfParseTypedef(entry, ctype) +{ + var name, type, ii; + + name = entry['name']; + if (typeof (entry['typedef']) != 'string') + throw (new Error('Malformed CTF JSON: typedef value in not ' + + 'a string')); + + type = entry['typedef']; + + /* + * We need to ensure that we're not looking at type that's one of our + * built in types. Traditionally in C a uint32_t would be a typedef to + * some kind of integer. However, those size types are built ins. + */ + for (ii = 0; ii < ctf_deftypes.length; ii++) { + if (name == ctf_deftypes[ii]) + return; + } + + ctype.typedef(name, type); +} + +function ctfParseStruct(entry, ctype) +{ + var name, type, ii, val, index, member, push; + + member = []; + if (!Array.isArray(entry['struct'])) + throw (new Error('Malformed CTF JSON: struct value is not ' + + 'an array')); + + for (ii = 0; ii < entry['struct'].length; ii++) { + val = entry['struct'][ii]; + if (!('name' in val)) + throw (new Error('Malformed CTF JSON: struct member ' + + 'missing name')); + + if (!('type' in val)) + throw (new Error('Malformed CTF JSON: struct member ' + + 'missing type')); + + if (typeof (val['name']) != 'string') + throw (new Error('Malformed CTF JSON: struct member ' + + 'name isn\'t a string')); + + if (typeof (val['type']) != 'string') + throw (new Error('Malformed CTF JSON: struct member ' + + 'type isn\'t a string')); + + /* + * CTF version 2 specifies array names as <type> [<num>] where + * as node-ctype does this as <type>[<num>]. + */ + name = val['name']; + type = val['type']; + index = type.indexOf(' ['); + if (index != -1) { + type = type.substring(0, index) + + type.substring(index + 1, type.length); + } + push = {}; + push[name] = { 'type': type }; + member.push(push); + } + + name = entry['name']; + ctype.typedef(name, member); +} + +function ctfParseEntry(entry, ctype) +{ + var ii, found; + + if (!('name' in entry)) + throw (new Error('Malformed CTF JSON: entry missing "name" ' + + 'section')); + + for (ii = 0; ii < ctf_entries.length; ii++) { + if (ctf_entries[ii] in entry) + found++; + } + + if (found === 0) + throw (new Error('Malformed CTF JSON: found no entries')); + + if (found >= 2) + throw (new Error('Malformed CTF JSON: found more than one ' + + 'entry')); + + if ('integer' in entry) { + ctfParseInteger(entry, ctype); + return; + } + + if ('float' in entry) { + ctfParseFloat(entry, ctype); + return; + } + + if ('typedef' in entry) { + ctfParseTypedef(entry, ctype); + return; + } + + if ('struct' in entry) { + ctfParseStruct(entry, ctype); + return; + } + + ASSERT(false, 'shouldn\'t reach here'); +} + +function ctfParseJson(json, ctype) +{ + var version, ii; + + ASSERT(json); + ASSERT(ctype); + if (!('metadata' in json)) + throw (new Error('Invalid CTF JSON: missing metadata section')); + + if (!('ctf2json_version' in json['metadata'])) + throw (new Error('Invalid CTF JSON: missing ctf2json_version')); + + version = json['metadata']['ctf2json_version']; + for (ii = 0; ii < ctf_versions.length; ii++) { + if (ctf_versions[ii] == version) + break; + } + + if (ii == ctf_versions.length) + throw (new Error('Unsuported ctf2json_version: ' + version)); + + if (!('data' in json)) + throw (new Error('Invalid CTF JSON: missing data section')); + + if (!Array.isArray(json['data'])) + throw (new Error('Malformed CTF JSON: data section is not ' + + 'an array')); + + for (ii = 0; ii < json['data'].length; ii++) + ctfParseEntry(json['data'][ii], ctype); +} + +exports.ctfParseJson = ctfParseJson; |