henrikrudstrom/oce-wrap

View on GitHub
tasks/swig.js

Summary

Maintainability
B
6 hrs
Test Coverage
module.exports = function(gulp) {
  const path = require('path');
  const fs = require('fs');
  const mkdirp = require('mkdirp');
  const async = require('async');
  const run = require('gulp-run');

  const render = require('../src/render.js');
  const settings = require('../src/settings.js');
  const headers = require('../src/headers.js');

  const exec = require('child_process').exec;
  const flags = '-javascript -node -c++ -DSWIG_TYPE_TABLE=occ.js';
  const otherFlags = '-w302,401,314,509,512 -DCSFDB -DHAVE_CONFIG_H -DOCC_CONVERT_SIGNALS'; // TODO:
  const include = ['-I/usr/include/node', `-I${settings.oce.include}`];

  function runSwig(moduleName, done) {
    const input = path.join(settings.paths.swig, `${moduleName}/module.i`);
    if (!fs.existsSync(input))
      return done();

    const output = path.join(settings.paths.cxx, `${moduleName}_wrap.cxx`);
    const includes = include.join(' ');

    mkdirp.sync(path.dirname(output));

    const cmd = `${settings.swig} ${flags} ${otherFlags} ${includes} -o ${output} ${input}`;
    exec(cmd, done);
  }

  function runSwigRuntimeHeader(moduleName, done){
    const input = path.join(settings.paths.swig, `${moduleName}/module.i`);
    if (!fs.existsSync(input))
      return done();

    const output = path.join(settings.paths.cxx, `${moduleName}_runtime.h`);
    const includes = include.join(' ');

    mkdirp.sync(path.dirname(output));

    const cmd = `${settings.swig} ${flags} ${otherFlags} ${includes} -external-runtime ${output}`;
    exec(cmd, done);
  }

  gulp.task('swig-clean', (done) =>
    run(`rm -rf ${settings.paths.swig}`, { silent: true }).exec(done)
  );

  // Copy hand written swig .i files from module folder
  gulp.task('swig-copy', function(done) {
    var modules = settings.build.modules.concat('common');
    async.parallel(modules.map((mod) => (cb) => {
      var src = path.join(settings.paths.definition, 'modules', mod);
      var swig = path.join(settings.paths.swig, mod);
      var cxx = path.join(settings.paths.cxx);
      var inc = path.join(settings.paths.inc);

      if (!fs.existsSync(src)) return cb();
      mkdirp.sync(swig);
      mkdirp.sync(cxx);
      mkdirp.sync(inc);
      return run(
        `cp -f ${src}/*.i ${swig}/\ncp -f ${src}/*.c* ${cxx}/\ncp -f ${src}/*.h* ${inc}/`, { silent: false }
      ).exec(cb);
    }), done);
  });

  gulp.task('swig-cxx', function(done) {
    async.parallel(
      settings.build.modules.map((mod) => (cb) => runSwig(mod, cb)),
      done
    );
  });

  gulp.task('swig-headers', function(done) {
    async.parallel(
      settings.build.modules.map((mod) => (cb) => runSwigRuntimeHeader(mod, cb)),
      done
    );
  });

  var replace = require('gulp-replace');
  gulp.task('swig-hack-handles', function() {
    var expr = /result = \(\w+_\w+ \*\)new \w+_\w+\(\(.*/g;
    gulp.src([`${settings.paths.cxx}/*_wrap.cxx`])
      .pipe(replace(expr, str => {
        var clsName = str.match(/\w+_\w+/)[0];
        if (clsName.startsWith('Handle_'))
          return str;
        if (!headers.get('Handle_' + clsName))
          return str;
        // TODO: swig should handle this somehow.
        var statement = `
    // hacked
    Handle_${clsName} *handle;
    handle = (Handle_${clsName} *)new Handle_${clsName}((${clsName} const *)(result));
    self->ToObject()->Set(
      SWIGV8_SYMBOL_NEW("_handle"), SWIG_NewFunctionPtrObj(handle, SWIGTYPE_p_Handle_Standard_Transient));`;

        return str + statement;
      }))
      .pipe(gulp.dest(settings.paths.cxx));
  });

  gulp.task('render-swig', function(done) {
    const configuredModules = settings.build.modules
      .filter(mod => !fs.existsSync(`${settings.paths.definition}/modules/${mod}/module.i`))
      .map(mod => path.join(settings.paths.config, mod + '.json'));

    render.write(settings.paths.swig, render('swig', configuredModules));
    return done();
  });

  gulp.task('tests-clean', (done) =>
    run(`rm -rf ${settings.paths.dist}/tests`, { silent: true }).exec(done)
  );
};