Skip to content

Instantly share code, notes, and snippets.

@Garciat
Created January 3, 2016 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Garciat/0a6c70a6ccf2d5df4e57 to your computer and use it in GitHub Desktop.
Save Garciat/0a6c70a6ccf2d5df4e57 to your computer and use it in GitHub Desktop.
<?php
function compileCPP(string $sourcePath, string $binaryPath): bool {
$descriptorspec = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
];
$cwd = '/tmp';
$process = proc_open("em++ $sourcePath -o $binaryPath", $descriptorspec, $pipes, $cwd);
if (is_resource($process)) {
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
echo stream_get_contents($pipes[2]);
fclose($pipes[2]);
$return_value = proc_close($process);
return $return_value === 0;
}
return false;
}
function runJS(string $sourcePath, string $input = null) {
$descriptorspec = [
0 => ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
];
$cwd = '/tmp';
$process = proc_open("node $sourcePath", $descriptorspec, $pipes, $cwd);
if (is_resource($process)) {
if ($input) {
fwrite($pipes[0], $input);
}
fclose($pipes[0]);
$proc_out = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$proc_err = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$exit_status = proc_close($process);
return ['exit' => $exit_status, 'out' => $proc_out, 'err' => $proc_err];
}
return null;
}
class CompilationException extends Exception { }
class ExecutionException extends Exception { }
class CPlusPlusSource {
private $sourcePath;
function __construct($sourcePath) {
$this->sourcePath = $sourcePath;
}
function compile(): CPlusPlusBinary {
$binaryPath = tempnam(sys_get_temp_dir(), 'emcc_') . '.js';
$r = compileCPP($this->sourcePath, $binaryPath);
if (!$r) {
throw new CompilationException();
}
$binary = new CPlusPlusBinary($binaryPath);
return $binary;
}
}
class CPlusPlusBinary {
private $binaryPath;
function __construct($binaryPath) {
$this->binaryPath = $binaryPath;
}
function execute(string $input = null): ExecutionResult {
$r = runJS($this->binaryPath, $input);
if ($r === null) {
throw new ExecutionException();
}
$result = new ExecutionResult($r['exit'], $r['out'], $r['err']);
return $result;
}
}
class ExecutionResult {
private $exitStatus;
private $processOut;
private $processErr;
function __construct($exitStatus, $processOut, $processErr) {
$this->exitStatus = $exitStatus;
$this->processOut = $processOut;
$this->processErr = $processErr;
}
function getExitStatus(): int {
return $this->exitStatus;
}
function getOutput(): string {
return $this->processOut;
}
function getError(): string {
return $this->processErr;
}
}
$src = new CPlusPlusSource('/home/garciat/Desktop/hello.cpp');
echo $src->compile()->execute('123')->getOutput(), PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment