mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-26 13:59:47 +01:00
compiler-vm: added -input flag for providing stdin input; added %b printf specifier to print base-2; bug-fixes
This commit is contained in:
parent
dd7f84ceff
commit
cf0fead036
@ -13,8 +13,8 @@ use warnings;
|
|||||||
# These are set automatically by the build/commit script
|
# These are set automatically by the build/commit script
|
||||||
use constant {
|
use constant {
|
||||||
BUILD_NAME => "PBot",
|
BUILD_NAME => "PBot",
|
||||||
BUILD_REVISION => 342,
|
BUILD_REVISION => 343,
|
||||||
BUILD_DATE => "2011-12-17",
|
BUILD_DATE => "2011-12-30",
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
CC_LOCAL=1
|
|
||||||
export CC_LOCAL
|
|
||||||
ulimit -c 50000
|
ulimit -c 50000
|
||||||
./compiler_vm_client.pl compiler "$@"
|
CC_LOCAL=1 ./compiler_vm_client.pl compiler "$@"
|
||||||
|
@ -27,7 +27,7 @@ sub server_listen {
|
|||||||
sub vm_stop {
|
sub vm_stop {
|
||||||
my $pid = shift @_;
|
my $pid = shift @_;
|
||||||
return if not defined $pid;
|
return if not defined $pid;
|
||||||
kill 'TERM', $pid;
|
kill 9, $pid;
|
||||||
waitpid($pid, 0);
|
waitpid($pid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,7 +39,8 @@ sub vm_start {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($pid == 0) {
|
if($pid == 0) {
|
||||||
my $command = 'qemu-system-x86_64 -M pc -hda /home/compiler/compiler-vm-image -m 128 -monitor tcp:127.0.0.1:4445,server,nowait -serial tcp:127.0.0.1:4444,server,nowait -boot c -loadvm 2 -nographic';
|
#system('cp /home/compiler/compiler-saved-vm-backup /home/compiler/compiler-saved-vm');
|
||||||
|
my $command = 'qemu-system-x86_64 -M pc -net none -hda /home/compiler/compiler-saved-vm -m 128 -monitor tcp:127.0.0.1:4445,server,nowait -serial tcp:127.0.0.1:4444,server,nowait -enable-kvm -boot c -nographic -loadvm 1';
|
||||||
my @command_list = split / /, $command;
|
my @command_list = split / /, $command;
|
||||||
exec(@command_list);
|
exec(@command_list);
|
||||||
} else {
|
} else {
|
||||||
@ -47,9 +48,24 @@ sub vm_start {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub vm_reset {
|
||||||
|
use IO::Socket;
|
||||||
|
|
||||||
|
my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 4445, Prot => 'tcp');
|
||||||
|
if(not defined $sock) {
|
||||||
|
print "Unable to connect to monitor: $!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print $sock "loadvm 1\n";
|
||||||
|
close $sock;
|
||||||
|
}
|
||||||
|
|
||||||
sub execute {
|
sub execute {
|
||||||
my ($cmdline) = @_;
|
my ($cmdline) = @_;
|
||||||
|
|
||||||
|
print "execute($cmdline)\n";
|
||||||
|
|
||||||
my ($ret, $result);
|
my ($ret, $result);
|
||||||
|
|
||||||
my $child = fork;
|
my $child = fork;
|
||||||
@ -61,7 +77,7 @@ sub execute {
|
|||||||
my $pid = open(my $fh, '-|', "$cmdline 2>&1");
|
my $pid = open(my $fh, '-|', "$cmdline 2>&1");
|
||||||
|
|
||||||
local $SIG{ALRM} = sub { print "Time out\n"; kill 'TERM', $pid; die "Timed-out\n"; };
|
local $SIG{ALRM} = sub { print "Time out\n"; kill 'TERM', $pid; die "Timed-out\n"; };
|
||||||
alarm(5);
|
alarm(7);
|
||||||
|
|
||||||
while(my $line = <$fh>) {
|
while(my $line = <$fh>) {
|
||||||
$result .= $line;
|
$result .= $line;
|
||||||
@ -71,21 +87,19 @@ sub execute {
|
|||||||
|
|
||||||
my $ret = $? >> 8;
|
my $ret = $? >> 8;
|
||||||
alarm 0;
|
alarm 0;
|
||||||
|
print "[$ret, $result]\n";
|
||||||
return ($ret, $result);
|
return ($ret, $result);
|
||||||
};
|
};
|
||||||
|
|
||||||
alarm 0;
|
alarm 0;
|
||||||
if($@ =~ /Timed-out/) {
|
if($@ =~ /Timed-out/) {
|
||||||
#kill 'TERM', $child;
|
|
||||||
return (-13, '[Timed-out]');
|
return (-13, '[Timed-out]');
|
||||||
}
|
}
|
||||||
|
|
||||||
print "[$ret, $result]\n";
|
|
||||||
|
|
||||||
return ($ret, $result);
|
return ($ret, $result);
|
||||||
} else {
|
} else {
|
||||||
waitpid($child, 0);
|
waitpid($child, 0);
|
||||||
#print "child exited, parent continuing\n";
|
print "child exited, parent continuing\n";
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,19 +113,19 @@ sub compiler_server {
|
|||||||
while (my $client = $server->accept()) {
|
while (my $client = $server->accept()) {
|
||||||
$client->autoflush(1);
|
$client->autoflush(1);
|
||||||
my $hostinfo = gethostbyaddr($client->peeraddr);
|
my $hostinfo = gethostbyaddr($client->peeraddr);
|
||||||
printf "[Connect from %s]\n", $hostinfo->name || $client->peerhost;
|
printf "[Connect from %s]\n", $client->peerhost;
|
||||||
eval {
|
eval {
|
||||||
my $lang;
|
my $lang;
|
||||||
my $nick;
|
my $nick;
|
||||||
my $code = "";
|
my $code = "";
|
||||||
|
|
||||||
local $SIG{ALRM} = sub { die 'Timed-out'; };
|
local $SIG{ALRM} = sub { die 'Timed-out'; };
|
||||||
alarm 1;
|
alarm 5;
|
||||||
|
|
||||||
while (my $line = <$client>) {
|
while (my $line = <$client>) {
|
||||||
$line =~ s/[\r\n]+$//;
|
$line =~ s/[\r\n]+$//;
|
||||||
next if $line =~ m/^\s*$/;
|
next if $line =~ m/^\s*$/;
|
||||||
alarm 1;
|
alarm 5;
|
||||||
print "got: [$line]\n";
|
print "got: [$line]\n";
|
||||||
|
|
||||||
if($line =~ /compile:end/) {
|
if($line =~ /compile:end/) {
|
||||||
@ -124,7 +138,7 @@ sub compiler_server {
|
|||||||
my ($ret, $result) = execute("./compiler_vm_client.pl $tnick -lang=$tlang $code");
|
my ($ret, $result) = execute("./compiler_vm_client.pl $tnick -lang=$tlang $code");
|
||||||
|
|
||||||
if(not defined $ret) {
|
if(not defined $ret) {
|
||||||
#print "parent continued\n";
|
print "parent continued\n";
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +151,7 @@ sub compiler_server {
|
|||||||
print $client $result . "\n";
|
print $client $result . "\n";
|
||||||
close $client;
|
close $client;
|
||||||
# child exit
|
# child exit
|
||||||
|
print "child exit\n";
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ my %languages = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
my %preludes = (
|
my %preludes = (
|
||||||
'C99' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n",
|
'C99' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n#include <stdbool.h>\n#include \"prelude.h\"\n\n",
|
||||||
'C' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n",
|
'C' => "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n\n",
|
||||||
'C++' => "#include <iostream>\n#include <cstdio>\n\nusing namespace std;\n\n",
|
'C++' => "#include <iostream>\n#include <cstdio>\n\nusing namespace std;\n\n",
|
||||||
);
|
);
|
||||||
@ -696,9 +696,12 @@ if($output =~ m/^\s*$/) {
|
|||||||
my $right_quote = chr(226) . chr(128) . chr(153);
|
my $right_quote = chr(226) . chr(128) . chr(153);
|
||||||
$output =~ s/$left_quote/'/g;
|
$output =~ s/$left_quote/'/g;
|
||||||
$output =~ s/$right_quote/'/g;
|
$output =~ s/$right_quote/'/g;
|
||||||
|
$output =~ s/\s*In function 'main':\s*//g;
|
||||||
|
$output =~ s/warning: unknown conversion type character 'b' in format\s+warning: too many arguments for format/info: conversion type character 'b' in format is a candide extension/g;
|
||||||
|
|
||||||
|
#$output =~ s/[\r\n]+/ /g;
|
||||||
|
#$output =~ s/\s+/ /g;
|
||||||
|
|
||||||
$output =~ s/[\r\n]+/ /g;
|
|
||||||
$output =~ s/\s+/ /g;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unless($got_run) {
|
unless($got_run) {
|
||||||
|
@ -138,7 +138,8 @@ sub interpret {
|
|||||||
$output = "[$result]\n";
|
$output = "[$result]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
($ret, $result) = execute(5, "./compiler_watchdog.pl");
|
my $user_input_quoted = quotemeta $user_input;
|
||||||
|
($ret, $result) = execute(5, "./compiler_watchdog.pl $user_input_quoted");
|
||||||
|
|
||||||
$result =~ s/^\s+//;
|
$result =~ s/^\s+//;
|
||||||
$result =~ s/\s+$//;
|
$result =~ s/\s+$//;
|
||||||
|
@ -165,6 +165,8 @@ sub reaper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $stdin_input = join ' ', @ARGV;
|
||||||
|
|
||||||
sub execute {
|
sub execute {
|
||||||
my ($cmdline) = @_;
|
my ($cmdline) = @_;
|
||||||
my ($ret, $result);
|
my ($ret, $result);
|
||||||
@ -176,7 +178,17 @@ sub execute {
|
|||||||
local $SIG{TERM} = sub { kill 'TERM', $child; };
|
local $SIG{TERM} = sub { kill 'TERM', $child; };
|
||||||
|
|
||||||
if($child == 0) {
|
if($child == 0) {
|
||||||
exec("$cmdline 2>&1");
|
if(length $stdin_input) {
|
||||||
|
my ($out, $in);
|
||||||
|
open2($out, $in, "$cmdline 2>&1");
|
||||||
|
print $in "$stdin_input\n";
|
||||||
|
while(<$out>) {
|
||||||
|
print $_ . "\n";
|
||||||
|
}
|
||||||
|
exit 0;
|
||||||
|
} else {
|
||||||
|
exec("$cmdline 2>&1");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
while(1) { sleep 10; }
|
while(1) { sleep 10; }
|
||||||
}
|
}
|
||||||
|
93
modules/compiler_vm/prelude.h
Normal file
93
modules/compiler_vm/prelude.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#if 1
|
||||||
|
#include <limits.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <printf.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
static int printf_binary_handler(FILE *s, const struct printf_info *info, const void *const *args)
|
||||||
|
{
|
||||||
|
const char *g = 0;
|
||||||
|
struct lconv *loc = 0;
|
||||||
|
int group = 0, arr = 0, total = 0, len, digits;
|
||||||
|
unsigned long long value = info->is_long_double ? *(const unsigned long long *)args[0] :
|
||||||
|
info->is_long ? *(const unsigned long *) args[0] :
|
||||||
|
info->is_char ? *(const unsigned char *) args[0] :
|
||||||
|
info->is_short ? *(const unsigned short *) args[0] :
|
||||||
|
*(const unsigned int *) args[0] ;
|
||||||
|
|
||||||
|
char buf[sizeof value * CHAR_BIT], *p = buf;
|
||||||
|
|
||||||
|
while(value) *p++ = '0' + (value & 1), value >>= 1;
|
||||||
|
len = p - buf;
|
||||||
|
digits = info->prec < 0 ? 1 : info->prec;
|
||||||
|
if(len > digits) digits = len;
|
||||||
|
if(info->alt) {
|
||||||
|
if(digits += -digits & 3) total = digits + (digits - 1) / 4 * !!info->group;
|
||||||
|
} else {
|
||||||
|
total = digits;
|
||||||
|
group = info->group && (loc = localeconv(), *(g = loc->grouping));
|
||||||
|
if(group) {
|
||||||
|
while(*g > 0 && *g < CHAR_MAX) {
|
||||||
|
if(digits - arr <= *g) break;
|
||||||
|
++total;
|
||||||
|
arr += *g++;
|
||||||
|
}
|
||||||
|
if(!*g) total += (digits - arr - 1) / g[-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(!info->left && info->width > total++) fprintf(s, "%lc", (wint_t)info->pad);
|
||||||
|
if(info->alt)
|
||||||
|
while(digits) {
|
||||||
|
fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
if(digits && !(digits % 4) && info->group) fputc('.', s);
|
||||||
|
}
|
||||||
|
else if(group) {
|
||||||
|
if(*g) {
|
||||||
|
while(digits > arr) fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
} else {
|
||||||
|
int j = (digits - arr) % g[-1];
|
||||||
|
if(!j) j = g[-1];
|
||||||
|
|
||||||
|
while(j--) fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
while(digits > arr) {
|
||||||
|
fputs(loc->thousands_sep, s);
|
||||||
|
for(j = 0; j < g[-1]; ++j) fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(digits) {
|
||||||
|
int i = *--g;
|
||||||
|
fputs(loc->thousands_sep, s);
|
||||||
|
while(i--) fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else while(digits) fputc(digits-- > len ? '0' : *--p, s);
|
||||||
|
|
||||||
|
while(info->left && info->width > total++) fputc(' ', s);
|
||||||
|
return total - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int printf_binary_arginfo(const struct printf_info *info, size_t n, int *types, int *sizes)
|
||||||
|
{
|
||||||
|
if(n < 1) return -1;
|
||||||
|
(void)sizes;
|
||||||
|
|
||||||
|
types[0] = info->is_long_double ? PA_INT | PA_FLAG_LONG_LONG :
|
||||||
|
info->is_long ? PA_INT | PA_FLAG_LONG :
|
||||||
|
info->is_char ? PA_CHAR :
|
||||||
|
info->is_short ? PA_INT | PA_FLAG_SHORT :
|
||||||
|
PA_INT ;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__ (( constructor )) static void printf_binary_register(void)
|
||||||
|
{
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
register_printf_specifier('b', printf_binary_handler, printf_binary_arginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STR(s) #s
|
||||||
|
#define REVEAL(s) STR(s)
|
Loading…
Reference in New Issue
Block a user