OR-1 dataflow CPU sketch
at main 99 lines 3.2 kB view raw
1'use strict'; 2// Descend into a directory structure and, for each file matching *.node, output 3// based on the imports found in the file whether it's an N-API module or not. 4 5const fs = require('fs'); 6const path = require('path'); 7 8// Read the output of the command, break it into lines, and use the reducer to 9// decide whether the file is an N-API module or not. 10function checkFile (file, command, argv, reducer) { 11 const child = require('child_process').spawn(command, argv, { 12 stdio: ['inherit', 'pipe', 'inherit'] 13 }); 14 let leftover = ''; 15 let isNapi; 16 child.stdout.on('data', (chunk) => { 17 if (isNapi === undefined) { 18 chunk = (leftover + chunk.toString()).split(/[\r\n]+/); 19 leftover = chunk.pop(); 20 isNapi = chunk.reduce(reducer, isNapi); 21 if (isNapi !== undefined) { 22 child.kill(); 23 } 24 } 25 }); 26 child.on('close', (code, signal) => { 27 if ((code === null && signal !== null) || (code !== 0)) { 28 console.log( 29 command + ' exited with code: ' + code + ' and signal: ' + signal); 30 } else { 31 // Green if it's a N-API module, red otherwise. 32 console.log( 33 '\x1b[' + (isNapi ? '42' : '41') + 'm' + 34 (isNapi ? ' N-API' : 'Not N-API') + 35 '\x1b[0m: ' + file); 36 } 37 }); 38} 39 40// Use nm -a to list symbols. 41function checkFileUNIX (file) { 42 checkFile(file, 'nm', ['-a', file], (soFar, line) => { 43 if (soFar === undefined) { 44 line = line.match(/([0-9a-f]*)? ([a-zA-Z]) (.*$)/); 45 if (line[2] === 'U') { 46 if (/^napi/.test(line[3])) { 47 soFar = true; 48 } 49 } 50 } 51 return soFar; 52 }); 53} 54 55// Use dumpbin /imports to list symbols. 56function checkFileWin32 (file) { 57 checkFile(file, 'dumpbin', ['/imports', file], (soFar, line) => { 58 if (soFar === undefined) { 59 line = line.match(/([0-9a-f]*)? +([a-zA-Z0-9]) (.*$)/); 60 if (line && /^napi/.test(line[line.length - 1])) { 61 soFar = true; 62 } 63 } 64 return soFar; 65 }); 66} 67 68// Descend into a directory structure and pass each file ending in '.node' to 69// one of the above checks, depending on the OS. 70function recurse (top) { 71 fs.readdir(top, (error, items) => { 72 if (error) { 73 throw new Error('error reading directory ' + top + ': ' + error); 74 } 75 items.forEach((item) => { 76 item = path.join(top, item); 77 fs.stat(item, ((item) => (error, stats) => { 78 if (error) { 79 throw new Error('error about ' + item + ': ' + error); 80 } 81 if (stats.isDirectory()) { 82 recurse(item); 83 } else if (/[.]node$/.test(item) && 84 // Explicitly ignore files called 'nothing.node' because they are 85 // artefacts of node-addon-api having identified a version of 86 // Node.js that ships with a correct implementation of N-API. 87 path.basename(item) !== 'nothing.node') { 88 process.platform === 'win32' 89 ? checkFileWin32(item) 90 : checkFileUNIX(item); 91 } 92 })(item)); 93 }); 94 }); 95} 96 97// Start with the directory given on the command line or the current directory 98// if nothing was given. 99recurse(process.argv.length > 3 ? process.argv[2] : '.');