1765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* 2765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Author: Heidi Pan <heidi.pan@intel.com> 3765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Copyright (c) 2015 Intel Corporation. 4765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 5765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Permission is hereby granted, free of charge, to any person obtaining 6765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * a copy of this software and associated documentation files (the 7765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * "Software"), to deal in the Software without restriction, including 8765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * without limitation the rights to use, copy, modify, merge, publish, 9765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * distribute, sublicense, and/or sell copies of the Software, and to 10765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * permit persons to whom the Software is furnished to do so, subject to 11765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * the following conditions: 12765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 13765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * The above copyright notice and this permission notice shall be 14765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * included in all copies or substantial portions of the Software. 15765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * 16765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */ 24765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 25765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// dependencies 26765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvar peg = require('pegjs') 27765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang , fs = require('fs') 28765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang , path = require('path') 29765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang , Promise = require('bluebird') 30765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang , _ = require('lodash') 31765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang , util = require('util'); 32765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 33765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 34765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// use promise-style programming rather than spaghetti callbacks 35765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun ZhangPromise.promisifyAll(fs); 36765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 37765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 38765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangvar xml2js = { 39765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 40765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // js-format specs 41765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // MODULE: <module name> 42765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // ENUMS: { 43765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <enum name>: { 44765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // type: <enum type>, 45765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <enum description> 46765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 47765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 48765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // ENUMS_BY_GROUP: { 49765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <enum type>: { 50765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <enum group description> 51765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // members: [ <enum name>, ... ] 52765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 53765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 54765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // METHODS: { 55765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <method name>: { 56765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <method description>, 57765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // params: { 58765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <param name>: { 59765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // type: <param type>, 60765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <param description > 61765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 62765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, 63765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // return: { 64765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // type: <return type>, 65765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <return description> 66765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 67765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 68765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 69765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // CLASSES: { 70765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <class name>: { 71765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <class description>, 72765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // parent: <parent class name>, 73765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // group: <group name>, 74765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // methods: { ... }, 75765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // variables: { 76765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <variable name>: { 77765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // type: <variable type>, 78765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <variable description> 79765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 80765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, 81765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // enums: { ... }, 82765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // enums_by_group: { ... } 83765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 84765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 85765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // CLASSGROUPS: { 86765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <group name>: { 87765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // description: <group description>, 88765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // classes: [ <class name>, ... ], 89765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // enums: { ... }, 90765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // enums_by_group: { ... } 91765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 92765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 93765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang MODULE: '', 94765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ENUMS: {}, 95765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ENUMS_BY_GROUP: {}, 96765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang METHODS: {}, 97765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang CLASSES: {}, 98765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang CLASSGROUPS: {}, 99765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 100765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 101765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // baseline c -> js type mapping 102765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang TYPEMAPS: { 103765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang '^(const)?\\s*(unsigned|signed)?\\s*(int|short|long|float|double|size_t|u?int\\d{1,2}_t)?$': 'Number', 104765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang '^bool$': 'Boolean', 105765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang '^(const)?\\s*(unsigned|signed)?\\s*(char|char\\s*\\*|std::string)$': 'String', // TODO: verify that swig does this mapping 106765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang '^void\\s*\\(\\s*\\*\\s*\\)\\s*\\(\\s*void\\s*\\*\\)\\s*$': 'Function' 107765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 108765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 109765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 110765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // custom c -> js type mapping for pointers 111765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // ARRAY_TYPEMAPS: { 112765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <pointer data type>: { 113765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // arrayType: <swig generated array type that will replace pointers of data type>, 114765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // classes: [ <class that contains arrayType>, ... ] 115765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 116765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 117765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // POINTER_TYPEMAPS: { 118765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <class that contains pointerType>: { 119765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // <c pointer data type>: <js swig generated pointer type that will replace pointers of data type>, ... 120765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // }, ... 121765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // } 122765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ARRAY_TYPEMAPS: {}, 123765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang POINTER_TYPEMAPS: {}, 124765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 125765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 126765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // add command line options for this module 127765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang addOptions: function(opts) { 128765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.opts = opts; 129765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return opts 130765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang .option('-i, --inputdir [directory]', 'directory for xml files', __dirname + '/xml/mraa') 131765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang .option('-c, --custom [file]', 'json for customizations') 132765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang .option('-t, --typemaps [directory]', 'directory for custom pointer type maps') 133765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang .option('-g, --imagedir [directory]', 'directory to link to where the images will be kept', '') 134765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang .option('-s, --strict', 'leave out methods/variables if unknown type') 135765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 136765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 137765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 138765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // parse doxygen xml -> js-format specs 139765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: figure out whether we need to document any protected methods/variables 140765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang parse: function() { 141765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var XML_GRAMMAR_SPEC = 'grammars/xml.peg'; 142765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var NAMESPACE_SPEC = xml2js.opts.inputdir + '/namespace' + xml2js.opts.module + '.xml'; 143765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var CLASS_SPEC = function(c) { return xml2js.opts.inputdir + '/' + c + '.xml'; } 144765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var TYPES_SPEC = xml2js.opts.inputdir + '/types_8h.xml'; 145765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.MODULE = xml2js.opts.module; 146765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return Promise.join(createXmlParser(XML_GRAMMAR_SPEC), 147765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.opts.typemaps ? initCustomPointerTypemaps(xml2js.opts.typemaps) : Promise.resolve(), 148765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang fs.readFileAsync(NAMESPACE_SPEC, 'utf8'), 149765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang fs.existsSync(TYPES_SPEC) ? fs.readFileAsync(TYPES_SPEC, 'utf8') : Promise.resolve(null), 150765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang function(xmlparser, ignore, xml, xml_types) { 151765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (xml_types != null) { 152765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.ENUMS, getEnums(xmlparser.parse(xml_types)[0], false)); 153765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.ENUMS_BY_GROUP, getEnums(xmlparser.parse(xml_types)[0], true)); 154765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 155765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_c = xmlparser.parse(xml)[0]; 156765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.ENUMS, getEnums(spec_c, false)); 157765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.ENUMS_BY_GROUP, getEnums(spec_c, true)); 158765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.METHODS, getMethods(spec_c)); 159765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(getSubclassNames(spec_c), function(className) { xml2js.CLASSES[className] = {} }); 160765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parseClasses = _.map(getSubclasses(spec_c), function(c) { 161765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(CLASS_SPEC(c), 'utf8').then(function(xml) { 162765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang try { 163765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_c = xmlparser.parse(xml)[0]; 164765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var className = getName(spec_c); 165765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.CLASSES[className], { 166765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: getDescription(spec_c), 167765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang parent: getParent(spec_c, className), 168765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums: getEnums(spec_c, false, className), 169765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums_by_group: getEnums(spec_c, true, className), 170765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang variables: getVariables(spec_c, className), 171765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang methods: getMethods(spec_c, className) 172765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 173765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } catch(e) { 174765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(e.toString() + ': class ' + className + ' was not parsed correctly.'); 175765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 176765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 177765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 178765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parseGroups = fs.readdirAsync(xml2js.opts.inputdir).then(function(files) { 179765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var groupxmlfiles = _.filter(files, function(fn) { 180765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((path.extname(fn) == '.xml') && (path.basename(fn).search(/^group/) != -1)); 181765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 182765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return Promise.all(_.map(groupxmlfiles, function(fn) { 183765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(xml2js.opts.inputdir + '/' + fn, 'utf8').then(function(xml) { 184765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_c = xmlparser.parse(xml)[0]; 185765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.isEmpty(getSubmodules(spec_c))) { 186765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var group = getName(spec_c); 187765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var classes = getSubclassNames(spec_c); 188765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSGROUPS[group] = { 189765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: getDescription(spec_c), 190765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang classes: classes 191765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 192765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(classes, function(c) { 193765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.has(xml2js.CLASSES, c)) { 194765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[c].group = group; 195765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 196765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Warning: Group ' + group + ' has unknown class ' + c); 197765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 198765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 199765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 200765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 201765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang })); 202765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 203765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return Promise.all(parseClasses.concat(parseGroups)); 204765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).then(function() { 205765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!_.isEmpty(xml2js.CLASSGROUPS)) { 206765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // try to categorize ungrouped classes, if any 207765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes')); 208765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped); 209765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(ungrouped, function(c) { 210765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(findUsage(c), function(group) { 211765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSGROUPS[group].classes.push(c); 212765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 213765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 214765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang grouped = _.flatten(_.pluck(_.values(xml2js.CLASSGROUPS), 'classes')); 215765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ungrouped = _.difference(_.keys(xml2js.CLASSES), grouped); 216765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // try to categorize ungrouped enums, if any 217765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(xml2js.ENUMS_BY_GROUP, function(enumGroupSpec, enumGroupName) { 218765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(findUsage(enumGroupName, true), function(c) { 219765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[c].enums_by_group[enumGroupName] = enumGroupSpec; 220765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(enumGroupSpec.members, function(enumName) { 221765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[c].enums[enumName] = xml2js.ENUMS[enumName]; 222765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang delete xml2js.ENUMS[enumName]; 223765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 224765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang delete xml2js.ENUMS_BY_GROUP[enumGroupName]; 225765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 226765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 227765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 228765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).then(function() { 229765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (xml2js.opts.custom && fs.existsSync(xml2js.opts.custom)) { 230765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(xml2js.opts.custom, 'utf8').then(function(custom) { 231765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang try { 232765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang customizeMethods(JSON.parse(custom)); 233765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } catch(e) { 234765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('invalid custom.json, ignored. ' + e.toString()); 235765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 236765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 237765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 238765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(xml2js.opts.custom ? ('Error: No such customization file exists: ' + xml2js.opts.custom) : 'No customizations given.'); 239765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 240765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).then(function() { 241765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang generateCustomPointerClasses(); 242765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang validateMethods(); 243765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang validateVars(); 244765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.pick(xml2js, 'MODULE', 'ENUMS', 'ENUMS_BY_GROUP', 'METHODS', 'CLASSES', 'CLASSGROUPS'); 245765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 246765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 247765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang}; 248765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 249765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 250765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// create an xml parser 251765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction createXmlParser(XML_GRAMMAR_SPEC) { 252765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(XML_GRAMMAR_SPEC, 'utf8').then(function(xmlgrammar) { 253765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return peg.buildParser(xmlgrammar); 254765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 255765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 256765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 257765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 258765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// configure c->js typemaps from custom swig directives 259765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// TODO: many built in assumptions based on current upm file structures & .i customizations 260765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction initCustomPointerTypemaps(typemapsdir) { 261765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readdirAsync(typemapsdir).then(function(dirs) { 262765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return Promise.all(_.map(dirs, function(dir) { 263765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // get all js*.i directives from class-specific subdirectories, to be parsed below for %typemaps directives 264765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readdirAsync(typemapsdir + '/' + dir).then(function(files) { 265765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var directive = _.find(files, function(fn) { 266765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((path.extname(fn) == '.i') && (path.basename(fn).search(/^js/) != -1)); 267765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 268765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var data = {}; 269765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (directive) { 270765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang data[dir] = typemapsdir + '/' + dir + '/' + directive; 271765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 272765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return data; 273765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).catch(function(e) { 274765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // get all .i directives from top level directory, and parse for %array_class directives 275765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (e.code == 'ENOTDIR') { 276765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var fn = dir; 277765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (path.extname(fn) == '.i') { 278765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(typemapsdir + '/' + fn, 'utf8').then(function(directives) { 279765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var arraytypes = _.filter(directives.split(/\n/), function(line) { 280765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (line.search(/^%array_class/) != -1); 281765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 282765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(arraytypes, function(arraytype) { 283765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parsed = arraytype.match(/%array_class\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/); 284765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (parsed) { 285765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var from = parsed[1]; 286765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var to = parsed[2]; 287765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.ARRAY_TYPEMAPS[from] = { arrayType: to, classes: [] }; 288765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 289765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Incorrectly parsed array_class from ' + fn + ': ' + arraytype); 290765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 291765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 292765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 293765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 294765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 295765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw e; 296765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 297765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 298765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang })); 299765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).then(function(__directivesFiles) { 300765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // parse for %typemaps & %pointer_functions directives 301765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var _directivesFiles = _.filter(__directivesFiles, function(data) { return !_.isEmpty(data); }); 302765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var directivesFiles = _.object(_.map(_directivesFiles, _.keys), _.flatten(_.map(_directivesFiles, _.values))); 303765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return Promise.all(_.map(directivesFiles, function(directivesFn, className) { 304765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return fs.readFileAsync(directivesFn, 'utf8').then(function(directives) { 305765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var typemaps = _.filter(directives.split(/\n/), function(line) { 306765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (line.search(/^%typemap/) != -1); 307765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 308765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(typemaps, function(typemap) { 309765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parsed = typemap.match(/%typemap\((in|out)\)[\s]+([A-Za-z0-9_]+[\s]*[\*])/); 310765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (parsed) { 311765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var dir = parsed[1]; // TODO: ignored for now 312765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var type = normalizePointer(parsed[2]); 313765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var datatype = getPointerDataType(type); 314765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.has(xml2js.ARRAY_TYPEMAPS, datatype)) { 315765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.ARRAY_TYPEMAPS[datatype].classes.push(className); 316765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 317765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (no %array_class directive found for ' + datatype + ')'); 318765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 319765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 320765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Ignored typemap from ' + directivesFn + ': ' + typemap.replace('{', '') + ' (only considering in/out typemaps of pointer types)'); 321765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 322765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 323765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var ptrfns = _.filter(directives.split(/\n/), function(line) { 324765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (line.search(/^%pointer_functions/) != -1); 325765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 326765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(ptrfns, function(ptrfn) { 327765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parsed = ptrfn.match(/%pointer_functions\(([A-Za-z0-9_]+)[\s]*,[\s]*([A-Za-z0-9_]+)\)/); 328765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (parsed) { 329765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var from = parsed[1]; 330765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var to = parsed[2]; 331765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!_.has(xml2js.POINTER_TYPEMAPS, className)) { 332765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.POINTER_TYPEMAPS[className] = {}; 333765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 334765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.POINTER_TYPEMAPS[className][from] = to; 335765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 336765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 337765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 338765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang })); 339765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 340765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 341765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 342765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 343765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// generate class specs for custom pointer types 344765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction generateCustomPointerClasses() { 345765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var arrayTypes = _.pluck(_.values(xml2js.ARRAY_TYPEMAPS), 'arrayType'); 346765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var pointerTypes = _.uniq(_.flatten(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.values))); 347765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(arrayTypes, function(arrayType) { 348765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var dataType = _.findKey(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == arrayType; }); 349765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[arrayType] = { 350765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Array of type ' + dataType + '.', 351765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums: {}, 352765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums_by_group: {}, 353765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang variables: {}, 354765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang methods: {} 355765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 356765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[arrayType].methods[arrayType] = { 357765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Instantiates the array.', 358765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: { 359765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang nelements: { 360765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: 'Number', 361765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'number of elements in the array' 362765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 363765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 364765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: {} 365765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 366765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[arrayType].methods.getitem = { 367765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Access a particular element in the array.', 368765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: { 369765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang index: { 370765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: 'Number', 371765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'index of array to read from' 372765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 373765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 374765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: { 375765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: getType(dataType), 376765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'the value of the element found at the given index of the array' 377765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 378765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 379765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[arrayType].methods.setitem = { 380765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Modify a particular element in the array.', 381765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: { 382765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang index: { 383765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: 'Number', 384765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'index of array to write to' 385765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 386765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang value: { 387765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: getType(dataType), 388765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'the value to set the element found at the given index of the array' 389765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 390765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 391765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: {} 392765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 393765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 394765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var pointerDataTypeMap = _.reduce(_.map(_.values(xml2js.POINTER_TYPEMAPS), _.invert), function(memo, typemap) { 395765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.extend(memo, typemap); 396765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, {}); 397765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(pointerTypes, function(pointerType) { 398765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var dataType = pointerDataTypeMap[pointerType]; 399765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[pointerType] = { 400765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Proxy object to data of type ' + dataType + '.', 401765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums: {}, 402765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang enums_by_group: {}, 403765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang variables: {}, 404765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang methods: {} 405765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 406765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[pointerType].methods[pointerType] = { 407765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Instantiates the proxy object.', 408765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: {}, 409765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: {} 410765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 411765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[pointerType].methods.value = { 412765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Get the value of the object.', 413765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: {}, 414765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: { 415765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: getType(dataType), 416765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'the value of the object' 417765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 418765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 419765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[pointerType].methods.assign = { 420765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'Set the value of the object.', 421765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: { 422765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang value: { 423765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: getType(dataType), 424765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: 'the value to set the object to' 425765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 426765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, 427765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: {} 428765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 429765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 430765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 431765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 432765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 433765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// search for usage of a type 434765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction findUsage(type, classOnly) { 435765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var filterClasses = function(fn) { return _.without(_.map(xml2js.CLASSES, fn), undefined); }; 436765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var usesType = function(classSpec, className) { 437765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var methodsOfType = (_.find(classSpec.methods, function(methodSpec, methodName) { 438765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((!_.isEmpty(methodSpec.return) && methodSpec.return.type == type) || 439765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang (_.contains(_.pluck(methodSpec.params, 'type'), type))); 440765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }) != undefined); 441765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var variablesOfType = _.contains(_.pluck(classSpec.variable, 'type'), type); 442765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((methodsOfType || variablesOfType) ? className : undefined); 443765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 444765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var extendsType = function(classSpec, className) { 445765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((classSpec.parent == type) ? className : undefined); 446765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 447765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var classes = _.union(filterClasses(usesType), filterClasses(extendsType)); 448765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (classOnly) { 449765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return classes; 450765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 451765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.without(_.uniq(_.pluck(_.pick(xml2js.CLASSES, classes), 'group')), undefined); 452765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 453765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 454765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 455765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 456765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// override autogenerated methods with custom configuration 457765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction customizeMethods(custom) { 458765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(custom, function(classMethods, className) { 459765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.extend(xml2js.CLASSES[className].methods, _.pick(classMethods, function(methodSpec, methodName) { 460765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return isValidMethodSpec(methodSpec, className + '.' + methodName); 461765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang })); 462765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 463765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 464765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 465765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 466765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// make sure methods have valid types, otherwise warn (& don't include if strict) 467765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction validateMethods() { 468765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.METHODS = _.pick(xml2js.METHODS, function(methodSpec, methodName) { 469765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return hasValidTypes(methodSpec, methodName); 470765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 471765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(xml2js.CLASSES, function(classSpec, className) { 472765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var valid = _.pick(classSpec.methods, function(methodSpec, methodName) { 473765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return hasValidTypes(methodSpec, className + '.' + methodName, className); 474765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 475765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (xml2js.opts.strict) { 476765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[className].methods = valid; 477765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 478765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 479765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 480765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 481765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 482765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// make sure variables have valid types, otherwise warn (& don't include if strict) 483765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction validateVars() { 484765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(xml2js.CLASSES, function(classSpec, className) { 485765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var valid = _.pick(classSpec.variables, function(varSpec, varName) { 486765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ofValidType(varSpec, className + '.' + varName, className); 487765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 488765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (xml2js.opts.strict) { 489765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang xml2js.CLASSES[className].variables = valid; 490765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 491765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 492765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 493765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 494765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 495765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// verify that the json spec is well formatted 496765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction isValidMethodSpec(methodSpec, methodName) { 497765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var valid = true; 498765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var printIgnoredMethodOnce = _.once(function() { console.log(methodName + ' from ' + path.basename(xml2js.opts.custom) + ' is omitted from JS documentation.'); }); 499765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang function checkRule(rule, errMsg) { 500765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!rule) { 501765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang printIgnoredMethodOnce(); 502765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(' ' + errMsg); 503765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang valid = false; 504765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 505765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 506765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(methodSpec, 'description'), 'no description given'); 507765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(methodSpec, 'params'), 'no params given (specify "params": {} for no params)'); 508765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(methodSpec.params, function(paramSpec, paramName) { 509765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(paramSpec, 'type'), 'no type given for param ' + paramName); 510765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(paramSpec, 'description'), 'no description given for param ' + paramName); 511765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 512765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(methodSpec, 'return'), 'no return given (specify "return": {} for no return value)'); 513765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(methodSpec.return, 'type'), 'no type given for return value'); 514765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang checkRule(_.has(methodSpec.return, 'description'), 'no description given for return value'); 515765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return valid; 516765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 517765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 518765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 519765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get enum specifications 520765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getEnums(spec_c, bygroup, parent) { 521765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_js = {}; 522765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumGroups = _.find(getChildren(spec_c, 'sectiondef'), function(section) { 523765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var kind = getAttr(section, 'kind'); 524765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((kind == 'enum') || (kind == 'public-type')); 525765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 526765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (enumGroups) { 527765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(enumGroups.children, function(enumGroup) { 528765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumGroupName = getText(getChild(enumGroup, 'name'), 'name'); 529765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumGroupDescription = getText(getChild(enumGroup, 'detaileddescription'), 'description'); 530765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumGroupVals = getChildren(enumGroup, 'enumvalue'); 531765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (bygroup) { 532765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[enumGroupName] = { 533765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: enumGroupDescription, 534765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang members: [] 535765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 536765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 537765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(enumGroupVals, function(e) { 538765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: get prefix as option 539765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumName = getText(getChild(e, 'name'), 'name').replace(/^MRAA_/, ''); 540765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var enumDescription = getText(getChild(e, 'detaileddescription'), 'description'); 541765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!bygroup) { 542765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[enumName] = { 543765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: enumGroupName, 544765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: enumDescription 545765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 546765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 547765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[enumGroupName].members.push(enumName); 548765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 549765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 550765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 551765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 552765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return spec_js; 553765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 554765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 555765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 556765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the name for the module/group/class 557765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getName(spec_c) { 558765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getText(getChild(spec_c, 'compoundname'), 'name').replace(xml2js.opts.module + '::', ''); 559765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 560765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 561765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 562765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the description for the module/group/class 563765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getDescription(spec_c) { 564765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getText(getChild(spec_c, 'detaileddescription'), 'description'); 565765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 566765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 567765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 568765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the classes (xml file names) for the given module 569765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getSubclasses(spec_c) { 570765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { 571765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getAttr(innerclass, 'refid'); 572765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 573765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 574765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 575765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 576765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the classes (class names) for the given module 577765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getSubclassNames(spec_c) { 578765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.map(getChildren(spec_c, 'innerclass'), function(innerclass) { 579765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getText(innerclass).replace(xml2js.opts.module + '::', ''); 580765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 581765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 582765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 583765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 584765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the submodules (xml file names) for the given module 585765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getSubmodules(spec_c) { 586765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.map(getChildren(spec_c, 'innergroup'), function(innergroup) { 587765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getAttr(innergroup, 'refid'); 588765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 589765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 590765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 591765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 592765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get parent class, if any 593765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getParent(spec_c, className) { 594765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var parent = getChild(spec_c, 'basecompoundref'); 595765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (parent) { 596765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang parent = getText(parent); 597765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!_.has(xml2js.CLASSES, parent)) { 598765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('WARNING: Class ' + className + ' has unknown parent class ' + parent); 599765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 600765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 601765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return parent; 602765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 603765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 604765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 605765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction hasParams(paramsSpec) { 606765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return !(_.isEmpty(paramsSpec) || 607765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang ((_.size(paramsSpec) == 1) && getText(getChild(paramsSpec[0], 'type')) == 'void')); 608765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 609765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 610765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 611765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get method specifications for top-level module or a given class 612765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// TODO: overloaded functions 613765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// TODO: functions w/ invalid parameter(s)/return 614765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getMethods(spec_c, parent) { 615765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_js = {}; 616765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var methods = _.find(getChildren(spec_c, 'sectiondef'), function(section) { 617765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var kind = getAttr(section, 'kind'); 618765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((kind == 'public-func') || (kind == 'func')); 619765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 620765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (methods) { 621765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(methods.children, function(method) { 622765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var methodName = getText(getChild(method, 'name'), 'name'); 623765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (methodName[0] != '~') { // filter out destructors 624765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang try { 625765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var description = getChild(method, 'detaileddescription'); 626765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var methodDescription = getText(description, 'description'); 627765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paramsSpec = getChildren(method, 'param'); 628765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var params = {}; 629765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (hasParams(paramsSpec)) { 630765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params = getParams(paramsSpec, getParamsDetails(description), methodName, parent); 631765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 632765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var returnSpec = getChild(method, 'type'); 633765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var retval = {}; 634765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!_.isEmpty(returnSpec)) { 635765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang retval = getReturn(returnSpec, getReturnDetails(description), methodName, parent); 636765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 637765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang methodName = getUniqueMethodName(methodName, spec_js, parent); 638765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[methodName] = { 639765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: methodDescription, 640765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang params: params, 641765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return: retval 642765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }; 643765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } catch(e) { 644765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log((parent ? (parent + '.') : '') + methodName + ' is omitted from JS documentation.'); 645765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(' ' + e.toString()); 646765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 647765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 648765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 649765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 650765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return spec_js; 651765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 652765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 653765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 654765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get a unique string to represent the name of an overloaded method 655765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getUniqueMethodName(methodName, module, parent) { 656765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (methodName in module) { 657765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang do { 658765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang methodName += '!'; 659765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } while (methodName in module); 660765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 661765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return methodName; 662765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 663765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 664765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 665765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get variable specifications for a class 666765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getVariables(spec_c, parent) { 667765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_js = {}; 668765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var vars = _.find(getChildren(spec_c, 'sectiondef'), function(section) { 669765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var kind = getAttr(section, 'kind'); 670765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (kind == 'public-attrib'); 671765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 672765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (vars) { 673765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(_.filter(vars.children, function(variable) { 674765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (getAttr(variable, 'kind') == 'variable'); 675765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }), function(variable) { 676765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var varName = getText(getChild(variable, 'name'), 'name'); 677765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var varType = getType(getText(getChild(variable, 'type')), parent); 678765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var varDescription = getText(getChild(variable, 'detaileddescription')); 679765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[varName] = { 680765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: varType, 681765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: varDescription 682765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 683765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 684765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 685765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return spec_js; 686765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 687765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 688765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 689765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get return value specs of a method 690765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getReturn(spec_c, details, method, parent) { 691765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var retType = getType(getText(spec_c, 'type'), parent); 692765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var retDescription = (details ? getText(details, 'description') : ''); 693765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ((retType == 'void') ? {} : { 694765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type: retType, 695765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang description: retDescription 696765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 697765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 698765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 699765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 700765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get paramater specs of a method 701765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getParams(spec_c, details, method, parent) { 702765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var spec_js = {}; 703765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(spec_c, function(param) { 704765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang try { 705765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paramType = getType(getText(getChild(param, 'type'), 'type'), parent); 706765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paramName = getText(getChild(param, 'declname'), 'name'); 707765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[paramName] = { type: paramType }; 708765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } catch(e) { 709765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (paramType == '...') { 710765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js['arguments'] = { type: paramType }; 711765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 712765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw e; 713765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 714765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 715765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 716765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(details, function(param) { 717765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var getParamName = function(p) { return getText(getChild(getChild(p, 'parameternamelist'), 'parametername'), 'name'); } 718765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paramName = getParamName(param); 719765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paramDescription = getText(getChild(param, 'parameterdescription'), 'description'); 720765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.has(spec_js, paramName)) { 721765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang spec_js[paramName].description = paramDescription; 722765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 723765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var msg = ' has documentation for an unknown parameter: ' + paramName + '. '; 724765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var suggestions = _.difference(_.keys(spec_js), _.map(details, getParamName)); 725765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var msgAddendum = (!_.isEmpty(suggestions) ? ('Did you mean ' + suggestions.join(', or ') + '?') : ''); 726765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Warning: ' + (parent ? (parent + '.') : '') + method + msg + msgAddendum); 727765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 728765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 729765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return spec_js; 730765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 731765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 732765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 733765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the equivalent javascript type from the given c type 734765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getType(type_c, parent) { 735765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var type_js = type_c; 736765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.find(xml2js.TYPEMAPS, function(to, from) { 737765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var pattern = new RegExp(from, 'i'); 738765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (type_c.search(pattern) == 0) { 739765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type_js = to; 740765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 741765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 742765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 743765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (isPointer(type_js)) { 744765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var dataType = getPointerDataType(type_js); 745765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var className = parent.toLowerCase(); 746765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.has(xml2js.ARRAY_TYPEMAPS, dataType) && _.contains(xml2js.ARRAY_TYPEMAPS[dataType].classes, className)) { 747765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type_js = xml2js.ARRAY_TYPEMAPS[dataType].arrayType; 748765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else if (_.has(xml2js.POINTER_TYPEMAPS, className) && _.has(xml2js.POINTER_TYPEMAPS[className], dataType)) { 749765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type_js = xml2js.POINTER_TYPEMAPS[className][dataType]; 750765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else if (_.has(xml2js.CLASSES, dataType)) { // TODO: verify that swig does this mapping 751765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type_js = dataType; 752765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 753765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang type_js = dataType + ' *' 754765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 755765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 756765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return type_js; 757765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 758765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 759765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 760765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// verify that all types associated with the method are valid 761765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction hasValidTypes(methodSpec, methodName, parent) { 762765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var valid = true; 763765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var msg = (xml2js.opts.strict ? ' is omitted from JS documentation.' : ' has invalid type(s).'); 764765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var printIgnoredMethodOnce = _.once(function() { console.log(methodName + msg); }); 765765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.each(methodSpec.params, function(paramSpec, paramName) { 766765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!isValidType(paramSpec.type, parent)) { 767765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang valid = false; 768765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang printIgnoredMethodOnce(); 769765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(' Error: parameter ' + paramName + ' has invalid type ' + typeToString(paramSpec.type)); 770765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 771765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 772765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (!_.isEmpty(methodSpec.return) && !isValidType(methodSpec.return.type, parent)) { 773765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang valid = false; 774765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang printIgnoredMethodOnce(); 775765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(' Error: returns invalid type ' + typeToString(methodSpec.return.type)); 776765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 777765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return valid; 778765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 779765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 780765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 781765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// verify that type of variable is valid 782765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction ofValidType(varSpec, varName, parent) { 783765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (isValidType(varSpec.type, parent)) { 784765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return true; 785765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 786765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var msgAddendum = (xml2js.opts.strict ? ' Omitted from JS documentation.' : ''); 787765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log('Error: ' + varName + ' is of invalid type ' + typeToString(varSpec.type) + '.' + msgAddendum); 788765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return false; 789765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 790765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 791765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 792765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 793765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// verify whether the given type is valid JS 794765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction isValidType(type, parent) { 795765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (_.contains(_.values(xml2js.TYPEMAPS), type) || 796765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.has(xml2js.CLASSES, type) || 797765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.has(xml2js.ENUMS_BY_GROUP, type) || 798765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.contains(['Buffer', 'Function', 'mraa_result_t'], type) || 799765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang _.has((parent ? xml2js.CLASSES[parent].enums_by_group : []), type) || 800765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang isValidPointerType(type, parent)); 801765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 802765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 803765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 804765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction isValidPointerType(type, parent) { 805765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var className = parent.toLowerCase(); 806765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var arrayTypemap = _.find(xml2js.ARRAY_TYPEMAPS, function(to) { return to.arrayType == type; }); 807765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var valid = ((arrayTypemap && _.contains(arrayTypemap.classes, className)) || 808765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang (_.has(xml2js.POINTER_TYPEMAPS, className) && (_.contains(_.values(xml2js.POINTER_TYPEMAPS[className]), type)))); 809765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return valid; 810765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 811765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 812765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 813765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// determines whether a type looks like a c pointer 814765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction isPointer(type) { 815765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (type.search(/\w+\s*(\*|&)$/) != -1); 816765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 817765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 818765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 819765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// remove extraneous whitespace from pointer types as canonical representation 820765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction normalizePointer(ptr) { 821765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ptr.replace(/\s*$/, ''); 822765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 823765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 824765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 825765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the data type of a pointer (e.g. int is the data type of int*) 826765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getPointerDataType(ptr) { 827765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return ptr.replace(/\s*(\*|&)$/, ''); 828765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 829765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 830765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 831765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// print more human friendly type for error messages 832765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction typeToString(type) { 833765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return type.replace('*', '*'); 834765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 835765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 836765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 837765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the detailed description of a method's parameters 838765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getParamsDetails(spec_c) { 839765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paras = getChildren(spec_c, 'para'); 840765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var details = _.find(_.map(paras, function(para) { 841765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getChild(para, 'parameterlist'); 842765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }), function(obj) { return (obj != undefined); }); 843765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return (details ? details.children : undefined); 844765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 845765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 846765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 847765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the detailed description of a method's return value 848765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getReturnDetails(spec_c) { 849765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var paras = getChildren(spec_c, 'para'); 850765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.find(_.map(paras, function(para) { 851765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return getChild(para, 'simplesect'); 852765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }), function(obj) { return ((obj != undefined) && (getAttr(obj, 'kind') == 'return')); }); 853765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 854765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 855765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 856765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get (and flatten) the text of the given object 857765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getText(obj, why) { 858765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: links ignored for now, patched for types for 859765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var GENERATE_LINK = function(x) { return x + ' '; } 860765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.reduce(obj.children, function(text, elem) { 861765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang if (_.isString(elem)) { 862765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += elem.trim() + ' '; 863765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else if (_.isPlainObject(elem)) { 864765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang switch(elem.name) { 865765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'para': 866765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += getText(elem, why) + ' \n'; 867765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'ref': 868765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += GENERATE_LINK(getText(elem, why)); 869765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'parameterlist': 870765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'simplesect': 871765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text; // to be handled elsewhere 872765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'programlisting': 873765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'htmlonly': 874765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text; // ignored 875765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: html doesn't seem to work for yuidoc, using markdown for now 876765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'itemizedlist': 877765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += '\n' + getText(elem, why) + ' \n \n'; 878765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'listitem': 879765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += '+ ' + getText(elem, why) + '\n'; 880765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'bold': 881765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += '__' + getText(elem, why).trim() + '__ '; 882765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'ulink': 883765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += '[' + getText(elem, why).trim() + '](' + getAttr(elem, 'url').trim() + ') '; 884765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'image': 885765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: copy images over; hard coded for now 886765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang var fn = getAttr(elem, 'name'); 887765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += ' \n \n![' + fn + '](' + xml2js.opts.imagedir + '/' + fn + ') '; 888765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'linebreak': 889765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += ' \n'; 890765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang case 'ndash': 891765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text += '– '; 892765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang default: 893765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang // TODO: incomplete list of doxygen xsd implemented 894765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.warn('NYI Unknown Object Type: ' + elem.name); 895765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return text; 896765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang //throw new Error('NYI Unknown Object Type: ' + elem.name); 897765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 898765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } else { 899765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang throw new Error('NYI Unknown Type: ' + (typeof elem)); 900765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang } 901765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }, '').trim(); 902765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 903765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 904765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 905765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the value of attribute with the given name of the given object 906765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getAttr(obj, name) { 907765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.find(obj.attr, function(item) { 908765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return item.name == name; 909765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }).value; 910765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 911765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 912765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 913765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get the child object with the given name of the given object 914765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getChild(obj, name) { 915765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.find(obj.children, function(child) { 916765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return child.name == name; 917765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 918765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 919765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 920765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 921765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// get all children objects with the given name of the given object 922765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction getChildren(obj, name) { 923765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return _.filter(obj.children, function(child) { 924765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang return child.name == name; 925765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang }); 926765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 927765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 928765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 929765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang// debug helper: print untruncated object 930765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangfunction printObj(obj) { 931765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang console.log(util.inspect(obj, false, null)); 932765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang} 933765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 934765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang 935765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangmodule.exports = xml2js;