#!/usr/bin/perl -W

# this perlscript calculates the offset of the variables located in the structure 'config_t'
# very useful for debugging via. a terminal program!

# usage: 'stru.pl global.h'

$struct_found = 0;
$byte_count = 0;
$cbyte_count = 0;

open OF, ">magicstr.h";
print OF "\n// Automatically generated file (bin/stru.pl), DO NOT EDIT directly\n\n";

while($l = <>) {
	chomp $l;
    $tag = 0;

    if ($l =~ /^\s*$/) { # skip empty lines
	next;
    } elsif ($l =~ /[\s\t]*\/\/\+(\d+)/) {  # find a tag in form of //+NUMBER
	if (defined($1)) {
	    $tag = 1;
	    $tag_size = $1;
	} 
    } elsif ($l =~ /^[\s\t]*\/\//) {  # skip lines consisting of comments only
	next;
    }
    
    if ($l =~ /^\s*struct config_t\s*{/) {
	$struct_found = 1;
	print "hex, dec\n";
    } elsif ($l =~ /\s*};/) {
	$struct_found = 0;
    } elsif ($struct_found == 1) {
	printf("%2X, %3d :%s", $byte_count, $byte_count, $l);

	# limited to 48 characters per displayed string
	($str) = ($l =~ /\s*\/\/\s*(.{1,54})/);	# comments after 2nd // ignored : (\s*\/\/)?
	
	$magicname = "_magic_str_". $cbyte_count;
	
	if ($tag == 1) {
	    $byte_count = $byte_count + $tag_size;
		# $cbyte_count is not increased
	} elsif ($l =~ /uint8_t \w+\[(\d+)\]/) {
	    $byte_count = $byte_count + $1;
		$cbyte_count += $1;
		print OF "char $magicname\[\] PROGMEM = \"$str\";\n";
		$arr .= $magicname .",\n";
		for ($i = $1 ; $i > 1; $i--){
			# a little space consuming (but space saving on the simple program...)
			$arr .= "NULL,";			# the previous non-NULL pointer will need to be searched
		}
		print OF "\n";
	} else {
	    $byte_count = $byte_count + 1;
		$cbyte_count ++;
		print OF "char $magicname\[\] PROGMEM = \"$str\";\n";
		$arr .= $magicname .",\n";
	}
    }
	
} # while

# ----------- Done with global.h parsing ---------

	# we pad variables to multiple of 16, so avr does not display silly things
	# at the end (but we can still write to silly places - the igntable)
	$i = $cbyte_count % 16;
	$magicname = "_magic_str_". $cbyte_count;
	if($i > 0){
		print OF "char $magicname\[\] PROGMEM = \"No more variable, go back, don't touch\";\n";
		$arr .= $magicname .",\n";
		$i--;
	}
	
	# if $i is still more than 0, we padd NULL pointers
	while($i > 0){
		$arr .= "NULL,";			# the previous non-NULL pointer will need to be searched
		$i--;
	}
	
	
print OF "\nPGM_VOID_P magicstr[] PROGMEM = {\n $arr NULL\n};\n";	# with the unnecessary NULL we just spare some coding for the last ','
close OF;
