mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-22 20:09:43 +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
|
||||
use constant {
|
||||
BUILD_NAME => "PBot",
|
||||
BUILD_REVISION => 342,
|
||||
BUILD_DATE => "2011-12-17",
|
||||
BUILD_REVISION => 343,
|
||||
BUILD_DATE => "2011-12-30",
|
||||
};
|
||||
|
||||
1;
|
||||
|
@ -1,6 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
CC_LOCAL=1
|
||||
export CC_LOCAL
|
||||
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 {
|
||||
my $pid = shift @_;
|
||||
return if not defined $pid;
|
||||
kill 'TERM', $pid;
|
||||
kill 9, $pid;
|
||||
waitpid($pid, 0);
|
||||
}
|
||||
|
||||
@ -39,7 +39,8 @@ sub vm_start {
|
||||
}
|
||||
|
||||
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;
|
||||
exec(@command_list);
|
||||
} 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 {
|
||||
my ($cmdline) = @_;
|
||||
|
||||
print "execute($cmdline)\n";
|
||||
|
||||
my ($ret, $result);
|
||||
|
||||
my $child = fork;
|
||||
@ -61,7 +77,7 @@ sub execute {
|
||||
my $pid = open(my $fh, '-|', "$cmdline 2>&1");
|
||||
|
||||
local $SIG{ALRM} = sub { print "Time out\n"; kill 'TERM', $pid; die "Timed-out\n"; };
|
||||
alarm(5);
|
||||
alarm(7);
|
||||
|
||||
while(my $line = <$fh>) {
|
||||
$result .= $line;
|
||||
@ -71,21 +87,19 @@ sub execute {
|
||||
|
||||
my $ret = $? >> 8;
|
||||
alarm 0;
|
||||
print "[$ret, $result]\n";
|
||||
return ($ret, $result);
|
||||
};
|
||||
|
||||
alarm 0;
|
||||
if($@ =~ /Timed-out/) {
|
||||
#kill 'TERM', $child;
|
||||
return (-13, '[Timed-out]');
|
||||
}
|
||||
|
||||
print "[$ret, $result]\n";
|
||||
|
||||
return ($ret, $result);
|
||||
} else {
|
||||
waitpid($child, 0);
|
||||
#print "child exited, parent continuing\n";
|
||||
print "child exited, parent continuing\n";
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
@ -99,19 +113,19 @@ sub compiler_server {
|
||||
while (my $client = $server->accept()) {
|
||||
$client->autoflush(1);
|
||||
my $hostinfo = gethostbyaddr($client->peeraddr);
|
||||
printf "[Connect from %s]\n", $hostinfo->name || $client->peerhost;
|
||||
printf "[Connect from %s]\n", $client->peerhost;
|
||||
eval {
|
||||
my $lang;
|
||||
my $nick;
|
||||
my $code = "";
|
||||
|
||||
local $SIG{ALRM} = sub { die 'Timed-out'; };
|
||||
alarm 1;
|
||||
alarm 5;
|
||||
|
||||
while (my $line = <$client>) {
|
||||
$line =~ s/[\r\n]+$//;
|
||||
next if $line =~ m/^\s*$/;
|
||||
alarm 1;
|
||||
alarm 5;
|
||||
print "got: [$line]\n";
|
||||
|
||||
if($line =~ /compile:end/) {
|
||||
@ -124,7 +138,7 @@ sub compiler_server {
|
||||
my ($ret, $result) = execute("./compiler_vm_client.pl $tnick -lang=$tlang $code");
|
||||
|
||||
if(not defined $ret) {
|
||||
#print "parent continued\n";
|
||||
print "parent continued\n";
|
||||
last;
|
||||
}
|
||||
|
||||
@ -137,6 +151,7 @@ sub compiler_server {
|
||||
print $client $result . "\n";
|
||||
close $client;
|
||||
# child exit
|
||||
print "child exit\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ my %languages = (
|
||||
);
|
||||
|
||||
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 <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);
|
||||
$output =~ s/$left_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) {
|
||||
|
@ -138,7 +138,8 @@ sub interpret {
|
||||
$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+$//;
|
||||
|
@ -165,6 +165,8 @@ sub reaper {
|
||||
}
|
||||
}
|
||||
|
||||
my $stdin_input = join ' ', @ARGV;
|
||||
|
||||
sub execute {
|
||||
my ($cmdline) = @_;
|
||||
my ($ret, $result);
|
||||
@ -176,7 +178,17 @@ sub execute {
|
||||
local $SIG{TERM} = sub { kill 'TERM', $child; };
|
||||
|
||||
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 {
|
||||
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