#! /bin/sh
#  /usr/local/bin/bash
## cloog2test2 for Cloog2Test
##
## Made by Louis-Noel Pouchet
## Contact: <louis-noel.pouchet@inria.fr>
##
## Started on  Tue May  2 14:30:19 2006 Louis-Noel Pouchet
## Last update Mon Nov 13 19:44:49 2006 Louis-Noel Pouchet
##


## Set this to bash if you experience some troubles on old systems.
##
SH_BINARY=/usr/local/bin/bash
SH_BINARY=/bin/sh

TEMPLATE=src/scripts/template


## Print the usage, and exit.
##
function usage()
{
    echo "Usage: cloog2test [options] filename";
    echo;
    echo "Filename must follow format XXX.cloog or XXX.c if -n option\
 is specified.";
    echo "A file named XXX.program must be located at the same place.";
    echo "Define CLOOG environment variable to set the path to CLooG.";
    echo "Options are:
-s	Add FIFO schedule (Linux only)
-c	Add cycle count (Linux only)
-t	Add time count
-n	No CLooG call
-k	Keep the Sed script
-v	Verbose output
-h	Print this help
-p ARG	Set input program file to ARG (no naming convention needed)
";
   exit 1;
}

## Read a string, and set program options.
##
function set_options()
{
    val="$1";
    count=1;
    opt=${val:$count:1}
    while [ "$opt" != "" ]; do
	case "$opt" in
	    s) FIFO_SCHEDULE="Y";;
	    c) CYCLE_COUNT="Y";;
	    t) TIME_COUNT="Y";;
	    n) NO_CLOOG="Y";;
	    k) KEEP_SED="Y";;
	    h) PRINT_HELP="Y";;
	    v) VERBOSE_OUTPUT="Y";;
	    p) INPUT_FILE="Y"; WITH_ARG="INPUT_FILE";
		count=$(($count + 1));
		opt=${val:$count:1}
		if ! [ -z "$opt" ]; then
		    usage;
		fi
		;;
	    *) echo "Unrecognized option: -$opt."; usage; exit 1;;
	esac;
	count=$(($count + 1));
	opt=${val:$count:1}
    done;
}


## Read the command line.
##
function read_parameters()
{
while [ $# -ne 0 ]; do
    case "$1" in
	-*) set_options "$1"
	    if ! [ -z "$WITH_ARG" ];
		then
		shift 1;
		eval $WITH_ARG="$1";
		WITH_ARG="";
	    fi
	    ;;
	 *) if ! [ -z "$FILENAME" ]; then
		usage;
	    fi
	    FILENAME="$1";
	    FILENAME_FULL="$1";
	    ;;
    esac;
    shift 1;
done;
}


## Remove the sed script if needed.
##
function rm_sed()
{
    if [ -z "$KEEP_SED" ]; then
	rm -f "$FILENAME.sed";
    fi
}


## Sed script generator. Reads the .program content, and create a sed
## script named FILE.sed.
##
# ## Generate parameters.


function the_sed_script_generator()
{
TheSedScriptGenerator='
FILENAME="$1";

## Generate statements.
count=1
var=S$count;
value=`eval echo -e "$""$var"`;
echo "
/__STATEMENTS__/ {
 c\\" >> "$FILENAME.sed"
while ! [ -z "$value" ]; do
    echo \
"$value\\" >> "$FILENAME.sed";
    count=$(($count + 1));
    var=S$count;
    value=`eval echo -e "$""$var"`;
done;
echo "
}" >> "$FILENAME.sed";


## Generate remainder.
echo "
/__INCLUDES__/ {
  c\\
\\
  `if [ -z "$INCLUDES" ]; \
	then echo "\\\\\";  \
	else echo -n "$INCLUDES"  | sed -e "s/\(.*\)/\1\\\\\/g"; \
   fi`

}

/__PROLOGUE__/ {
  c\\
\\
  `count=1;\
var=PARVAL$count;\
value=\`eval echo "$""$var"\`;\
while ! [ -z "$value" ]; do\
     echo "\\\\\";\
     count=$(($count + 1));\
     var=PARVAL$count;\
     value=\`eval echo "$""$var"\`;\
done;\
  if [ -z "$PROLOGUE" ]; \
	then echo "\\\\\";  \
	else echo -n "$PROLOGUE"  | sed -e "s/\(.*\)/\1\\\\\/g"; \
   fi`
'

TheSedScriptGenerator="$TheSedScriptGenerator"'\\

}
" >> "$FILENAME.sed";


echo "
'

TheSedScriptGenerator="$TheSedScriptGenerator"'
/__EPILOGUE__/ {
  c\
`
if [ -z "$EPILOGUE" ]; \
	then echo "\\\\\";  \
	else echo -n "$EPILOGUE"  | sed -e "s/\(.*\)/\1\\\\\/g" | grep -v "^n"; \
   fi`

}

/__PREKERNEL__/ {
  c\
`
if [ -z "$PREKERNEL" ]; \
	then echo "\\\\\";  \
	else echo -n "$PREKERNEL"  | sed -e "s/\(.*\)/\1\\\\\/g" | grep -v "^n"; \
   fi`

}
/__POSTKERNEL__/ {
  c\
`
if [ -z "$POSTKERNEL" ]; \
	then echo "\\\\\";  \
	else echo -n "$POSTKERNEL"  | sed -e "s/\(.*\)/\1\\\\\/g" | grep -v "^n"; \
   fi`

}
" >> "$FILENAME.sed";
'
}


function main()
{
    read_parameters "$@";
    if [ -z "$FILENAME" ] || ! [ -z "$PRINT_HELP" ]; then usage; fi;

    ## Set appropriate filename.
    if [ -z "$NO_CLOOG" ]; then
	FILENAME=${FILENAME%.cloog};
    else
	FILENAME=${FILENAME%.c};
    fi

    ## Exit if filename extension is invalid.
    if [ "$FILENAME" = "$FILENAME_FULL" ]; then
	usage;
    fi

    ## Check if a file named FILE.program exists.
    ##
    if ! [ -f "$FILENAME.program" ] && [ -z "$INPUT_FILE" ]; then
      echo -e "\033[31mA file named \"$FILENAME.program\" is expected.\033[0m";
      exit 1;
    fi

    ## Set CLooG binary name.
    if [ -z "$CLOOG" ]; then
	CLOOG=cloog;
    fi

    ## Generate the sed script.
    the_sed_script_generator "x$FIFO_SCHEDULE" "x$CYCLE_COUNT" "x$TIME_COUNT";
    if [ -z "$INPUT_FILE" ]; then
	head=`cat "$FILENAME.program"`;
    else
	head=`cat "$INPUT_FILE"`;
    fi
    echo "$head\n$TheSedScriptGenerator" | "$SH_BINARY" -s "$FILENAME";

    if ! [ -z "$VERBOSE_OUTPUT" ]; then
	echo -e "\033[36mProcessing file $FILENAME_FULL.\033[0m";
    fi

    ## Run CLooG.
   if [ -z "$NO_CLOOG" ]; then
	if ! [ -z "$VERBOSE_OUTPUT" ]; then
 	    $CLOOG -cpp 1 "$FILENAME_FULL" -o "$FILENAME.c";
 	else
 	    $CLOOG -cpp 1 "$FILENAME_FULL" -o "$FILENAME.c" &>/dev/null;
 	fi
 	if [ $? -ne 0 ]; then
 	    $CLOOG -cpp 1 "$FILENAME_FULL" -o "$FILENAME.c";
 	    echo -e "\033[31mFile $FILENAME_FULL not processed by CLooG\
  (an error occured).\033[0m";
 	    rm_sed;
 	    exit 1;
 	fi
	if ! [ -z "$VERBOSE_OUTPUT" ]; then
	    echo -e "\033[32mFile $FILENAME.c generated by CLooG.\033[0m";
	fi
   fi;

    ## Run the sed script.
    tmp_file=`mktemp /tmp/cloog2test.XXXXXX`
    if [ $? -ne 0 ]; then echo "mktemp error."; exit 1; fi
    sed -f "$FILENAME.sed" "$TEMPLATE.c" > "$tmp_file";
    if [ $? -ne 0 ]; then
	echo -e "\033[31mFile $FILENAME_FULL not modified (an error\
 occured).\033[0m";
	rm_sed;
	rm -f "$tmp_file";
	exit 1;
    fi
    ## Add the kernel code to the C file, and the event list.
    IFS='
'
    while read n; do
	if [ "$n" = "__KERNEL__" ]; then
	    FC="$FC"`cat $FILENAME.c`;
	else if [ "$n" = "__EVENTLIST__" ]; then
	    FC="$FC"`cat $EVENTLIST`;
	else
	    FC="$FC$n";
	fi fi
	FC="$FC$IFS";
    done < "$tmp_file"
    echo "$FC" > "$FILENAME.c"
    if ! [ -z "$VERBOSE_OUTPUT" ]; then
    echo -e "\033[32mFile $FILENAME.c modified with $FILENAME.program.\033[0m";
    fi
    ## Be clean.
    rm_sed;
    rm -f "$tmp_file";
}


## Call the main.
main "$@"
