reader-cproto-parser.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. const stream = require('stream');
  2. const split2 = require('split2');
  3. const pumpify = require('pumpify');
  4. const SPLIT_COMMENT = /^\/\* cephes\/([a-z0-9]+)\.c \*\/$/;
  5. const SPLIT_PROTO = /^(double|int) cephes_([a-z0-9]+)\(([A-Za-z0-9_ ,*\[\]]+)\);$/;
  6. const SPLIT_ARG = /^(double|int) (\*)?(?:cephes_)?([A-Za-z0-9]+)(\[\])?$/;
  7. class CprotoLineParser extends stream.Transform {
  8. constructor() {
  9. super({ objectMode: true });
  10. this._currentFilename = '';
  11. }
  12. _parseFilename(comment) {
  13. const [, filename ] = comment.match(SPLIT_COMMENT);
  14. this._currentFilename = filename;
  15. }
  16. _parseProto(proto) {
  17. const [
  18. , returnType, functionName, functionArgsStr
  19. ] = proto.match(SPLIT_PROTO);
  20. const functionArgs = functionArgsStr.split(/, ?/).map(function (arg) {
  21. const [, mainType, pointer, name, array] = arg.match(SPLIT_ARG);
  22. return {
  23. type: mainType,
  24. isPointer: pointer === '*',
  25. name: name,
  26. isArray: array === '[]',
  27. isArrayLength: false,
  28. fullType: `${mainType}${pointer || ''}${array || ''}`
  29. };
  30. });
  31. let lastIsArray = false;
  32. for (const functionArg of functionArgs) {
  33. if (lastIsArray && functionArg.name.toLowerCase() === 'n') {
  34. functionArg.isArrayLength = true;
  35. }
  36. lastIsArray = functionArg.isArray;
  37. }
  38. this.push({
  39. returnType,
  40. functionName,
  41. functionArgs,
  42. filename: this._currentFilename
  43. });
  44. }
  45. _transform(line, encoding, done) {
  46. if (line.startsWith('/*')) {
  47. this._parseFilename(line);
  48. } else {
  49. this._parseProto(line);
  50. }
  51. done(null);
  52. }
  53. }
  54. function cprotoParser() {
  55. return pumpify.obj(
  56. split2(),
  57. new CprotoLineParser()
  58. );
  59. }
  60. module.exports = cprotoParser;