#! /usr/local/bin/perl -w

use strict;

sub quote_string {
    my $s = shift;
    $s =~ s/([\\\"])/\\$1/g;
    $s =~ s/\n/\\n/g;
    $s =~ s/\r/\\r/g;
    $s =~ s/\t/\\t/g;
    $s =~ s/([\000-\037])/sprintf("\\%03o",ord($1))/eg;
    return $s;
}

my $new_path = shift @ARGV;
if ( ! defined($new_path) ) {
    print STDERR "Syntax is: unix-curry.pl <program> [extra args]\n";
    exit 1;
}

print "/* This file is automatically generated.  Do not edit! */\n";

print <<'__EOF__';
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
__EOF__

printf ("\nconst char *new_path = \"%s\";\n", quote_string($new_path));
print "\nconst char * const extra_argv[] = {\n";
foreach my $arg ( @ARGV ) {
    printf ("  \"%s\",\n", quote_string($arg));
}
print "};\n";
print "\n";

print <<'__EOF__';
const int extra_argc = sizeof(extra_argv)/sizeof(char *);

void
OOM (void)
{
  fprintf (stderr, "Out of memory!\n");
  exit (EXIT_FAILURE);
}

int
main (int argc, char * const *argv)
{
  char **new_argv;
  int i, j;

  new_argv = malloc ((extra_argc+argc+1)*sizeof(char *));
  if ( ! new_argv )
    OOM ();
  i = 0;
#if 1
  new_argv[i++] = argv[0];
#else
  new_argv[i] = malloc (strlen (new_path) + 1);
  if ( ! new_argv[i] )
    OOM ();
  strcpy (new_argv[i++], new_path);
#endif
  for ( j=0 ; j<extra_argc ; j++ )
    {
      new_argv[i] = malloc (strlen (extra_argv[j]) + 1);
      if ( ! new_argv[i] )
        OOM ();
      strcpy (new_argv[i++], extra_argv[j]);
    }
  for ( j=1 ; j<argc ; j++ )
    new_argv[i++] = argv[j];
  new_argv[i] = NULL;
  execv (new_path, new_argv);
  fprintf (stderr, "execv() failed!\n");
  exit (EXIT_FAILURE);
}
__EOF__
