# File : substractNegPools.body.make.pl
# Author : NTM
# Created : 20/01/05
#
#
# Copyright (C) Nicolas Thierry-Mieg, 2006.
#
#
# This file is part of InterPool, written by 
# Nicolas Thierry-Mieg (CNRS, France) Nicolas.Thierry-Mieg@imag.fr
#
# InterPool is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InterPool is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with InterPool; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


# This script opens substractNegPools.body.c, copies it
# into $outputFile while stripping some of the comments, and appends to it
# the body of substractNegPoolsFromUnitsInclInval, obtained
# by copying the body of substractNegPoolsFromUnits and removing
# the #ifdef DO_NOT_DEFINE and corresponding #endifs.
# NOTE: comment stripping is rudimentary, not all comments are stripped but
# I believe anything stripped is indeed comments. The purpose of stripping
# them is just to make the file harder to read, so anybody opening the
# file by accident realizes that something is wrong (you should always edit
# the source file, ie substractNegPools.body.c; never the bodyFull version!)

use warnings ;
use strict ;

# name of the source file
my $inputFile = "substractNegPools.body.c" ;

# name of the file to create
my $outputFile = "substractNegPools.bodyFull.c" ;


open(INPUT, "$inputFile") || 
    die "in substractNegPools.body.make.pl, cannot open $inputFile for reading\n" ;

open (OUTPUT, ">$outputFile") || 
    die "in substractNegPools.body.make.pl, cannot open $outputFile for writing\n" ;


# print a header so nobody tries to edit the output file
print(OUTPUT "/************** DO NOT EDIT THIS FILE! ********************/\n") ;
print(OUTPUT "/******* THIS IS MADE AUTOMATICALLY BY  substractNegPools.body.make.pl *********/\n") ;
print(OUTPUT "/************* CONTENT WILL BE SQUASHED!! *****************/\n") ;
print(OUTPUT "/******* YOU SHOULD EDIT $inputFile INSTEAD ****************/\n\n\n") ;


# store text to print for substractNegPoolsFromUnitsInclInval in a scalar
my $toPrint = "" ;

# inComment: true iff we are in a comment block */
my $inComment = 0 ;

# only has meaning inside a DO_NOT_DEFINE block:
# number of opened #ifdef's since and including the last #ifdef DO_NOT_DEFINE
my $nbIfDef = 0 ;

# tmp variable
my $line ;

while(<INPUT>)
{
    chomp ;

    if ($inComment)
    {
	if (! m~\*/~)
	{
	    # no end-of-comment in this line, we are still in a flowing comment block
	    next ;
	}
	else
	{
	    # we were in a comment block, but comment ends on this line
	    if (m~\*/\S+~)
	    {
		# damn, there is some stuff after the end of comment, print a mangled line
		$line = "/* MANGLED: $_\n" ;
		$toPrint .= $line ;
		print(OUTPUT $line) ;
		next ;
	    }
	    else
	    {
		# end-of-comment ends the line
		$inComment = 0 ;
		next ;
	    }
	}
    }

    elsif (m~^unitClosures\* substractNegPoolsFromUnits~)
    {
	# this is the declaration of the function: print, and rename in $toPrint
	print(OUTPUT "$_\n") ;
	s~^unitClosures\* substractNegPoolsFromUnits~unitClosures* substractNegPoolsFromUnitsInclInval~ ;
	$toPrint .= "$_\n" ;
	next ;
    }

    elsif (m~^\#ifdef DO_NOT_DEFINE~)
    {
	$nbIfDef = 1 ;
	next ;
    }

    elsif ($nbIfDef > 0)
    {
	# we are in a DO_NOT_DEFINE
	if (m~^\#ifdef~)
	{
	    # another ifdef block starts: increment nbIfDef and print only to $toPrint
	    $nbIfDef++ ;
	    $toPrint .= "$_\n" ;
	    next ;
	}
	elsif (m~^\#endif~)
	{
	    # end of ifdef block
	    if ($nbIfDef == 1)
	    {
		# it's actually the end of the DO_NOT_DEFINE block
		$nbIfDef = 0 ;
		next ;
	    }
	    else
	    {
		# we were in a secondary ifdef
		$nbIfDef-- ;
		$toPrint .= "$_\n" ;
		next ;
	    }
	}
	else
	{
	    # regular line in the ifdef block
	    $toPrint .= "$_\n" ;
	    next ;
	}
    }

    elsif (m~/\*~)
    {
	#line has a begin-comment and is not in an ifdef DO_NOT_DEFINE block
	if (! m~\*/~)
	{
	    # no end-of-comment in this line, we are beginning a flowing comment block
	    $inComment = 1 ;
	    s~\s*/\*.*$~~ ; # remove the comment part
	    if ($_)
	    {
		# if some text remains, print it
		# sanity check: we don't want anymore begin-comment here!
		if (m~/\*~)
		{
		    die "in substractNegPools.body.make.pl, begin-comment still present!\n" ;
		}
		$line = "$_\n" ;
		$toPrint .= $line ;
		print(OUTPUT $line) ;
	    }
	    next ;
	}
	else
	{
	    # there is an end-of-comment, just print the line (don't bother
	    # trying to see if there is any code after the comment)
	    $line = "$_\n" ;
	    $toPrint .= $line ;
	    print(OUTPUT $line) ;
	    next ;
	}
    }

    else
    {
	# we are not in a comment block or an ifdef block, and current line does not 
	# contain a begin-comment: print it in both funcs
	$line = "$_\n" ;
	$toPrint .= $line ;
	print(OUTPUT $line) ;
	next ;
    }
}


# now print a warning, and print $toPrint

print(OUTPUT "\n\n\n/***** AUTOGENERATED BY substractNegPools.body.make.pl ****/\n\n") ;
print(OUTPUT $toPrint) ;

