#! perl

use Text::Balanced qw(extract_bracketed);
use Data::Dumper;

die "$0: Usage $0 FILE.c" unless $#ARGV == 0;

my $file = shift @ARGV;

$file =~ s/\.c$//;

my $infile = $file . '.c';
my $outfile = $file . '.str';

die "$0: $infile: $!" unless -e $infile;

print <<"HEADER";
/*
 * !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
 *
 * This file is generated automatically from '$infile'
 * by $0.
 *
 * Any changes made here will be lost!
 *
 */

#define CONCAT(a,b) a##b
#define _S(name) (__PARROT_STATIC_STR(__LINE__))
#define __PARROT_STATIC_STR(line) CONCAT(&static_string_, line)
#include <parrot/pobj.h>

#if ! DISABLE_GC_DEBUG
#  define GC_DEBUG_VERSION ,0
#else
#  define GC_DEBUG_VERSION
#endif

HEADER

my %known_strings = ();

sub output_string {
  my ($text, $line) = @_;

  if (exists $known_strings{$text}) {
    <<"DATA";
#define static_string_${line} static_string_$known_strings{$text}

DATA
  }
  else {
    $known_strings{$text} = $line;
    <<"DATA";
static const char static_string_${line}_data\[\] = $text;
static const struct parrot_string_t static_string_${line} = {
  { /* pobj_t */
    {{
      (void* const)static_string_${line}_data,
      sizeof(static_string_${line}_data)
    }},
    PObj_constant_FLAG
    GC_DEBUG_VERSION
  },
  sizeof(static_string_${line}_data),
  (void* const)static_string_${line}_data,
  sizeof(static_string_${line}_data) - 1,
  1,
  0
};

DATA
  }
}

open IN, $infile;

my $line = 0;
while (<IN>) {
  $line++;
  next if m/^\s*\#/; # ignore preprocessor
  next unless s/.*\b_S\b//;

  my $str = extract_bracketed $_, '(")';

  print output_string (substr($str,1,-1), $line);
}
