-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode_test.js
More file actions
122 lines (106 loc) · 4.02 KB
/
code_test.js
File metadata and controls
122 lines (106 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
var child_process = require('child_process'),
path = require('path'),
fs = require('fs'),
EventEmitter = require('events').EventEmitter,
stream = require('stream'),
util = require('util');
var config = {
programs: 'programs',
replace: '#define USER_DATA'
},
templates = {},
sanitizers = [];
exports.config = function(_config) {
for(var property in _config) {
if(typeof _config[property] !== 'undefined') {
config[property] = _config[property];
}
}
};
exports.sanitizer = function(fn) {
sanitizers.push(fn);
};
exports.load = function(templateName, templateFile, fn) {
if(typeof templateName === 'string' && typeof templateFile === 'string') {
loadTemplate(templateName, templateFile, fn);
} else if(typeof templateName === 'string' && typeof templateFile === 'function') {
loadTemplate(templateName, path.join(config.programs, templateName + '.cpp'), templateFile);
} else {
fs.readdir(config.programs, function(err, files) {
if(err) return console.warn(err);
files.forEach(function(file) {
loadTemplate(file.split('.')[0], path.join(config.programs, file), templateName || function(){});
});
})
}
};
exports.run = function(template, code, out, err) {
sanitizers.forEach(function(sanitizer){
code = sanitizer.call(this, code) || code;
});
var _template = templates[template],
source = _template.toString().replace(config.replace, code);
compileAndRun(source, out, err);
};
exports.run2 = function(template, code, runningProgram) {
sanitizers.forEach(function(sanitizer) {
code = sanitizer.call(this, code) || code;
});
var _template = templates[template],
source = _template.toString().replace(config.replace, code);
compileAndRun2(source, runningProgram);
};
function loadTemplate(templateName, templateFile, fn) {
console.info('Loading template %s %s', templateName, templateFile);
fs.readFile(templateFile, function(err, data) {
if(err) return console.warn(err);
templates[templateName] = data;
if(fn)
fn();
});
}
function compileAndRun(source, outStream, errStream) {
var compiler = child_process.exec('g++ -x c++ -o compiled -', function(err, stdout, stderr) {
if(err) return console.warn('[g++ execution error] %s', err);
var program = child_process.exec('./compiled');
if(outStream) program.stdout.pipe(outStream);
if(errStream) program.stderr.pipe(errStream);
program.on('exit', function(code, signal) {
console.log('program exited with code %s and signal %s', code, signal);
});
});
compiler.stdin.end(source);
}
function compileAndRun2(source, runningProgram) {
var compiler = child_process.exec('g++ -x c++ -o compiled -', function(err, stdout, stderr) {
if(err) return runningProgram.emit('err', 'execution error'); //TODO parse g++ error
var program = child_process.exec('./compiled');
//runningProgram.stdout = program.stdout;
//runningProgram.stderr = program.stderr;
program.stdout.pipe(runningProgram.stdout);
program.stderr.pipe(runningProgram.stderr);
program.on('exit', function(code, signal) {
if(signal == 'SIGSEGV') {
runningProgram.emit('err', 'segfault', {});
}
});
});
compiler.stdin.end(source);
}
// returns object with type and info
function parseGPlusPlusError(err) {
//TODO
};
function RunningProgram() {
EventEmitter.call(this);
this.stdout = null;
this.stderr = null;
}
util.inherits(RunningProgram, EventEmitter);
/*
RunningProgram events
---------------------
'err', function(type, data) {};
'end', function(output) {};
*/
exports.RunningProgram = RunningProgram;