lep / pjass

The famous jass syntax checker.
BSD 2-Clause "Simplified" License
25 stars 6 forks source link

Stdin processing #2

Closed juvian closed 3 years ago

juvian commented 3 years ago

Is it possible to process multiple files via stdin? Tried concatenating common.j + '\n' + blizzard.j but does not seem to be working (trying to parse wa3map.j from a map with a custom blizzard.j without having to dump the blizzard.j file to disk).

lep commented 3 years ago

No, not really. pjass likes to conform to the "jass standard" which means a file can only have one globals section, etc. Hence i don't see it happening. But i'm curious how you actually dev your map/call pjass in particular. Because there are some ways that might be enough for you like:

$ somehow-extract-blizzard.j | pjass common.j - war3map.j

Or if you use Bash as your shell you could use anonymous FDs

$ pjass <(cat tests/common.j ) <(cat tests/Blizzard.j )
Parse successful:     2621 lines: /dev/fd/63
Parse successful:    10255 lines: /dev/fd/62
Parse successful:    12876 lines: <total>

where cat is just a stand-in for whatever way you could have to get your .j files.

juvian commented 3 years ago

Oh its not for a specific map but my translation tool https://github.com/juvian/wc3-translate. Recently had a case where google translated a \into a \ and that change ended up making map unhostable, which was quite tricky to find as the error line warcraft reported was wrong for some reason. But your tool gives accurate line number so wanted to integrate that into the workflow to be sure the translations did not break script.

For most maps I could just do pjass common.j blizzard.j and then stream the war3map.j but have several cases such as this one that comes with a custom scripts/blizzard.j file which has some custom functions used by map there, so if I just use blizzard's blizzard.j have many errors of those functions not defined. Using a mpq reader so ideally wanted to avoid writing the scripts/blizzard.j file before calling your tool and then having to delete it but its not a big issue, will just do that. Code (which is not working) is something like this:

  const common = map.readFile('scripts/common.j') || fs.readFileSync('./data/common.j');
  const blizzard = map.readFile('scripts/blizzard.j') || fs.readFileSync('./data/blizzard.j');
  const promise = exec('pjass -');
  const child = promise.child;

  child.stdout.on('data', function(data) {
      console.log(data);
  });

  child.stdin.write(common);
  child.stdin.write(Buffer.from('\n'));
  child.stdin.write(blizzard);
  child.stdin.write(Buffer.from('\n'));
  child.stdin.write(map.script.buffer);
  child.stdin.end();

  await promise;
lep commented 3 years ago

Yeah, seems reasonable. You could try to use fs.createWriteStream. But i haven't tested it myself.

juvian commented 3 years ago

Doesn't seem possible in node and even with only script file with stdin it wasn't working so did all with files