mirror of
				https://github.com/pragma-/pbot.git
				synced 2025-11-04 00:27:23 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env perl
 | 
						|
 | 
						|
# File: vm-exec
 | 
						|
#
 | 
						|
# Purpose: Process and send commands to the PBot virtual machine on the
 | 
						|
# default TCP port (5555). Use the PBOTVM_SERIAL environment variable to
 | 
						|
# override the port. E.g., to use port 7777 instead:
 | 
						|
#
 | 
						|
# $ PBOTVM_SERIAL=7777 vm-exec -lang=sh echo test
 | 
						|
 | 
						|
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
 | 
						|
# SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
use warnings;
 | 
						|
use strict;
 | 
						|
 | 
						|
use File::Basename;
 | 
						|
use JSON::XS;
 | 
						|
 | 
						|
use FindBin qw($RealBin);
 | 
						|
use lib "$RealBin/../lib";
 | 
						|
 | 
						|
use constant {
 | 
						|
    SERIAL_PORT => $ENV{PBOTVM_SERIAL} // 5555,
 | 
						|
};
 | 
						|
 | 
						|
my $json = join ' ', @ARGV;
 | 
						|
 | 
						|
my $args = eval { decode_json $json };
 | 
						|
 | 
						|
if ($@) {
 | 
						|
    # wasn't JSON; make structure manually
 | 
						|
    if ($json =~ s/^-lang=([^ ]+)//) {
 | 
						|
      $args = { lang => $1, code => $json };
 | 
						|
    } else {
 | 
						|
      $args = { code => $json };
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
if (not exists $args->{code}) {
 | 
						|
    die "Usage: $0 <code>\n";
 | 
						|
}
 | 
						|
 | 
						|
# set any missing fields to default values
 | 
						|
$args->{nick}      //= 'vm';
 | 
						|
$args->{channel}   //= 'vm';
 | 
						|
$args->{lang}      //= 'c11';
 | 
						|
$args->{'vm-port'} //= SERIAL_PORT;
 | 
						|
 | 
						|
my $language = lc $args->{lang};
 | 
						|
 | 
						|
eval {
 | 
						|
    require "Languages/$language.pm";
 | 
						|
} or do {
 | 
						|
    my $found = 0;
 | 
						|
    my ($languages, $comma) = ('', '');
 | 
						|
 | 
						|
    foreach my $module (sort glob "$RealBin/../lib/Languages/*.pm") {
 | 
						|
        $module = basename $module;
 | 
						|
        $module =~ s/.pm$//;
 | 
						|
        next if $module =~ m/^_/;
 | 
						|
 | 
						|
        require "Languages/$module.pm" or die $!;
 | 
						|
        my $mod = "Languages::$module"->new;
 | 
						|
 | 
						|
        if (exists $mod->{name} and $mod->{name} eq $language) {
 | 
						|
            $language = $module;
 | 
						|
            $found = 1;
 | 
						|
            last;
 | 
						|
        }
 | 
						|
 | 
						|
        $module = $mod->{name} if exists $mod->{name};
 | 
						|
        $languages .= "$comma$module";
 | 
						|
        $comma = ', ';
 | 
						|
    }
 | 
						|
 | 
						|
    if (not $found) {
 | 
						|
        print "Language '$language' is not supported.\nSupported languages are: $languages\n";
 | 
						|
        exit;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
if (not length $args->{code}) {
 | 
						|
    if (exists $args->{usage}) {
 | 
						|
        print "$args->{usage}\n";
 | 
						|
    } else {
 | 
						|
        print "Usage: cc [-lang=<language>] [-info] [-paste] [-args \"command-line arguments\"] [compiler/language options] <code> [-stdin <stdin input>]\n";
 | 
						|
    }
 | 
						|
    exit;
 | 
						|
}
 | 
						|
 | 
						|
my $lang = "Languages::$language"->new(%{$args});
 | 
						|
 | 
						|
$lang->{local} = $ENV{CC_LOCAL};
 | 
						|
 | 
						|
$lang->process_interactive_edit;
 | 
						|
$lang->process_standard_options;
 | 
						|
$lang->process_custom_options;
 | 
						|
$lang->process_cmdline_options;
 | 
						|
$lang->preprocess_code;
 | 
						|
$lang->execute;
 | 
						|
$lang->postprocess_output;
 | 
						|
$lang->show_output;
 |