var decodeValueFns = { group: decodeSet, pairwise: decodeSet, key_mgmt: decodeSet, proto: decodeSet, eap: decodeSet, ctrl_interface: decodeObj, driver_param: decodeObj, } function defaultDecodeValue(value) { try { return JSON.parse(value) } catch(e) {} var m = /^"(.*)"$/.exec(value) if (m) return m[1] return value } function decodeSet(value) { return value.split(' ') } function decodeObj(str) { var obj = {} str.split(' ').map(decodeProperty).forEach(function (prop) { obj[prop.name] = prop.value }) return obj } function decodeProperty(line) { var m = /^([^=]*)=(.*)$/.exec(line) if (!m) return var name = m[1] var decodeValue = decodeValueFns[name] || defaultDecodeValue return {name: name, value: decodeValue(m[2])} } module.exports = function decodeConfig(txt) { var lines = txt.split(/\s*[\n\r]+\s*/g) var state = 'begin' var preNetworkComments = [] var prop var network var conf = { networks: [] } lines.forEach(function (line) { line = line.trim() switch (state) { case 'begin': if (line[0] === '#') { preNetworkComments.push(line.substr(1)) } else if (/^network={/.test(line)) { state = 'network' network = {} conf.networks.push(network) if (preNetworkComments.length > 0) { network._comment = preNetworkComments.join('\n') preNetworkComments = [] } } else if (prop = decodeProperty(line)) { conf[prop.name] = prop.value if (preNetworkComments.length > 0) { // should comments before global config items be handled? preNetworkComments = [] } } break case 'network': if (line[0] === '#') { // should comments in network blocks be handled? } else if (line === '}') { state = 'begin' } else if (prop = decodeProperty(line)) { network[prop.name] = prop.value } else { throw new Error('unexpected line in network block: ' + line) } break } }) return conf }