use strict;

my $ns   = shift @ARGV;
my $name = shift @ARGV;
my $out  = shift @ARGV;
my $in   = shift @ARGV;
my $var  = ( $name =~ s,[ /+.-],_,gr );
my $cmd  = "$ENV{cxx} -std=c++17 -x c++ -c -o \"$out\" -";

local $/;
open IN, $in or die "error opening $in";
my $data = <IN>;
my $len = length $data;

$data =~ s:([^a-zA-Z0-9 {}()<>.#+*/_',;=^-]):"\\x" . sprintf("%02x", ord($1)):ge;
$data =~ s:\\x0a:\\x0a"\n":gsm;
$data =~ s:(\\x[0-9a-f]{2})([a-fA-F0-9]):$1""$2:g;

open OUT, "|$cmd" or die "error starting $cmd";
print OUT "#include <string_view>\n";
print OUT "namespace divine::str::${ns} {\n";
print OUT "extern const std::string_view str_${var}( \n";
print OUT '"';
print OUT $data;
print OUT "\", $len ); }";
close OUT or die "error running $cmd: $!";
