File mttroot/mtt/bin/trans/mtt_header artifact 61f3b439e7 part of check-in ef3ac62298


#!/bin/sh
     ###################################### 
     ##### Model Transformation Tools #####
     ######################################

# Bourne shell script: mtt_header
# Headings for functions
# Copyright (C) 2000 by Peter J. Gawthrop

###############################################################
## Version control history
###############################################################
## $Id$
## $Log$
## Revision 1.29  2001/03/27 13:10:23  geraint
## Improved determination of Octave version.
##
## Revision 1.28  2001/02/17 03:48:17  geraint
## Use assignment LHS to gather tmp variable names.
## Prevents collection of long expressions, eg: tmp34*(tmp75
##
## Revision 1.27  2001/02/14 06:06:34  geraint
## Removed octave_value_list wrappers from standalone.exe - speed improvements
##
## Revision 1.26  2001/02/05 08:50:58  geraint
## Octave 2.1.x compatability.
##
## Revision 1.28  2001/01/17 21:16:15  geraint
## uncomment parameter assignments in .m reps
##
## Revision 1.27  2001/01/14 23:51:26  geraint
## declare parameters as variables instead of constants
##
## Revision 1.26  2001/01/07 21:22:47  geraint
## Compatibility with Octave 2.1.x
## vector_value ---> column_vector_value
##
## Revision 1.25  2000/12/05 12:05:26  peterg
## Changed to () form
##
## Revision 1.24  2000/12/05 10:04:52  peterg
## Fixed dummy variable bug
##
## Revision 1.23  2000/12/05 09:47:50  peterg
## Include crs as c files
##
## Revision 1.22  2000/12/04 12:19:12  peterg
## Changed $() to `` and $() to expr for sh compatibility -- geraint
##
## Revision 1.21  2000/12/04 08:52:40  peterg
## Zapped () in functions for sh compatibility
##
## Revision 1.20  2000/12/04 08:19:27  peterg
## Added switch declarations - in logic.cc
##
## Revision 1.19  2000/12/03 16:11:43  peterg
## Corrected bug in logic declatations
##
## Revision 1.18  2000/12/03 16:06:22  peterg
## Fixed bug in generating dummies
## Added logic declarations
##
## Revision 1.17  2000/12/01 20:55:01  peterg
## Added Geraint's fix for zeroing matrices
##
## Revision 1.16  2000/12/01 17:56:30  peterg
## Removed spurious  echo '## Set matrices to zero' - thanks Geraint
##
## Revision 1.15  2000/11/29 21:06:16  peterg
## Removed Npar creation - not needed??
##
## Revision 1.14  2000/11/27 11:51:43  peterg
## Added zero matrices in matlab code
##
## Revision 1.13  2000/11/09 17:19:52  peterg
## Geraint's pow() mods
##
## Revision 1.12  2000/11/09 16:09:46  peterg
## Declare dummy variables (mtt_s1 etc)
##
## Revision 1.11  2000/11/09 15:29:35  peterg
## lower-case declarations
##
## Revision 1.10  2000/11/07 17:20:51  peterg
## useful-functions.hh now included locally
##
## Revision 1.9  2000/11/07 16:56:24  peterg
## Version from Geraint
##
## Revision 1.2  2000/11/03 00:55:42  geraint
## typo: missed out 'd' in mttedx
## todo: need to accommodate mttsimpar
##
## Revision 1.1  2000/11/02 04:28:39  geraint
## Initial revision
##
## Revision 1.8  2000/10/17 16:35:03  peterg
## No parameter,state or input conversion in txt files
##
## Revision 1.7  2000/10/17 09:53:20  peterg
## Fixed logic rep
##
## Revision 1.6  2000/10/17 08:37:23  peterg
## Included logic rep
##
## Revision 1.5  2000/10/14 09:12:14  peterg
## No dies arguments and output itself
##
## Revision 1.4  2000/10/14 06:49:31  peterg
## Make parameter listing representation dependent
##
## Revision 1.3  2000/10/11 08:59:15  peterg
## Added csex rep
##
## Revision 1.2  2000/10/11 08:01:42  peterg
## Added noglobal fudge
##
## Revision 1.1  2000/10/10 21:02:27  peterg
## Initial revision
##
###############################################################

# Arguments
system=$1
rep=$2
language=$3
fun_name=${1}_${2}
#args=$4
#output=$5
#extras=$6

# Find system constants
Nx=`mtt_getsize $system x` # States
Nxx=`mtt_getsize $system xx` # States x States
Nu=`mtt_getsize $system u` # Inputs 
Ny=`mtt_getsize $system y` # Outputs 
Nyz=`mtt_getsize $system yz` # Zero outputs
##Npar=`wc -l $system\_sympar.txt | awk '{print $1}'`

# get octave version
octave_development=`octave --version | awk '{print $4}' | awk -F\. '{print $2}'`
case `$MATRIX --version | awk -F\. '{print $2}'` in
    0) # stable
	vector_value=vector_value
	;;
    1) # development
	vector_value=column_vector_value
	;;
    *)
	vector_value=column_vector_value
	;;
esac


# Representation-specific stuff

eqnargs='mttx,mttu,mttt,mttpar'
inputeqnargs='mttx,mtty,mttt,mttpar'
case $rep in
    cse)
	states=yes;
        inputs=yes;
	parameters=yes;
        output='mttdx,mtte'
        args=$eqnargs
	;;
    csex)
	states=yes;
        inputs=yes;
	parameters=yes;
        output=mttedx
        args=$eqnargs
	;;
    cseo)
	states=yes;
        inputs=yes;
	parameters=yes;
        output=mtty
        args=$eqnargs
	;;
    dm)
	states=no;
	inputs=no;
	parameters=yes;
        output='mtta,mttb,mttc,mttd,mtte'
        args=mttpar
        zeromatrices='a b c d e';
	;;
   input)
	states=yes;
	inputs=no;
	parameters=yes;
        output=mttu
        args=$inputeqnargs
        declareinputs=yes
	;;
    logic)
	states=no;
	inputs=no;
	parameters=yes;
        output=mttopen
        args=$eqnargs
        declareinputs=yes
        declarestates=yes
	declareswitches=yes
	;;
    numpar)
	states=no;
	inputs=no;
	parameters=no;
        output='mttpar'
	;;
    ode)
	states=yes;
        inputs=yes;
	parameters=yes;
        output='mttdx'
        args=$eqnargs
	;;
    odeo)
	states=yes;
        inputs=yes;
	parameters=yes;
        output='mtty'
        args=$eqnargs
	;;
    ode2odes)
	states=no;
        inputs=no;
	parameters=no;
        output='mtt_data'
        args='x0,par,simpar'
	;;
    simpar)
	states=no;
	inputs=no;
	parameters=no;
        output='mttsimpar'
	;;
    sm)
	states=no;
	inputs=no;
	parameters=yes;
        output='mtta,mttb,mttc,mttd'
        args=mttpar;
        zeromatrices='a b c d';
	;;
     smxa)
	states=no;
        inputs=no;
	parameters=yes;
        output='mtta'
        args=$eqnargs
	;;
    smxax)
	states=no;
        inputs=no;
	parameters=yes;
        output='mttax'
        args=$eqnargs
	;;
    state)
	states=no;
	inputs=no;
	parameters=yes;
        output=mttx
        args=mttpar
        declarestates=yes
	;;
    *)
	echo Representation $rep not supported - sorry; exit 1
esac

## Sort out parentheses
if [ -n "$args" ]; then
    Args='('$args')'
fi
if [ -n "$output" ]; then
    Output="[$output] = "
fi


# Lanuage specific stuff
case $language in
    m)
	Lc='##';
	Rc='';
	Lb='(';
	Rb=')';
	function="function"
	declaration="$Output$1_$rep$Args;"
	noglobals=true; # Fudge to make mtt_m2p work
        start='## BEGIN Code'
        finish='## END Code'
        var_declaration=
        declarestates=no
        declareinputs=no
	declareswitches=no
	;;
    txt)
	modeline='## -*-octave-*- Put Emacs into octave-mode ##';
	Lc='##';
	Rc='';
	Lb='(';
	Rb=')';
	function=""
	declaration=""
        start=''
        parameters=no
	states=no
	inputs=no
        declarestates=no
        declareinputs=no
	declareswitches=no
	;;
    oct)
	modeline="// -*-c++-*- Put Emacs into c++-mode";
	Lc='//';
	oct_header=yes;
        constant_declaration="const double "
        var_declaration="double "
	minusone="-1"
	map="_map"
        declaredummies=yes
	;;
    *)
	echo Language $language not supported - sorry; exit 1
esac

if [ "$rep" = "simpar" ]; then
   output=${output}${map}    # Output is simpar_map in this case
fi

zero_matrices()
{
## Set matrices to zero
echo
 ## echo '## Set matrices to zero'
for name in $zeromatrices; do
    case $name in
	a)
	    N=$Nx; M=$Nx
	    ;;
	b)
	    N=$Nx; M=$Nu
	    ;;
	c)
	    N=$Ny; M=$Nx
	    ;;
	d)
	    N=$Ny; M=$Nu
	    ;;
	e)
	    N=$Nx; M=$Nx
	    ;;
	*)
	    
    esac
    echo "   mtt$name = zeros($N,$M);"
done
}

declare_dummies()
{
# Get the dummies
dummies="mtt_tmp"
rm -f mtt_dummies
for dummy in $dummies; do
    grep "${dummy}[0-9]*[ \t\n]*=" < ${fun_name}.m |\
    awk '{ 
          if (match($1,dummy)==1)
             print $1
         }' dummy=$dummy >> mtt_dummies
done

dummy_list=`sort -u mtt_dummies`

# Comments
cat <<EOF

$Lc  Declarations of dummies $Rc
EOF

for dummy in $dummy_list; do
    echo '  ' $var_declaration $dummy';'
done
} # declare_dummies

declare_switches ()
{
cat <<EOF

$Lc  Declarations of switches $Rc
EOF
 strip_comments <${system}_switch.txt |\
 awk '{printf("  double %s_logic = 0;\n", tolower($1))}' 
} # declare_switches

declare_vars()
{
# Grab the names
names=`awk '{if ($1==var_type) print tolower($4)}' var_type=$1 ${system}_struc.txt`

# Comments
cat <<EOF

$Lc  Declarations for $1 names $Rc
EOF
# Declarations
for name in $names; do
    echo '  '$var_declaration $name';'
done
}


array2constant()
{
# Parameters
if [ "$parameters" = "yes" ]; then
cat <<EOF

$Lc Parameters $Rc
EOF
sympar2par_txt2m ${system} ""  "$var_declaration" "$minusone"
fi

# States
if [ "$states" = "yes" ]; then
cat <<EOF

$Lc States $Rc
EOF
N=`n2m 1 $Nx`
for i in $N; do
    echo $constant_declaration 'mttx'$i' = mttx('$i$minusone');'
done
fi

if [ "$declarestates" = "yes" ]; then
  declare_vars state
fi

# Inputs
if [ "$inputs" = "yes" ]; then
cat <<EOF

$Lc Inputs $Rc
EOF

N=`n2m 1 $Nu`
for i in $N; do
  echo $constant_declaration 'mttu'$i' = mttu('$i$minusone');'
done
fi

if [ "$declareinputs" = "yes" ]; then
  declare_vars input
fi

if [ "$declaredummies" = "yes" ]; then
  declare_dummies
fi

if [ "$declareswitches" = "yes" ]; then
  declare_switches
fi


zero_matrices;

}

# Argument specific stuff
get_arg_specific_stuff ()
{
    arg_name=${1:-""}
    case ${arg_name} in
	mtta | mtte)
	    arg_type="Matrix"
	    arg_size="(MTTNX,MTTNX)"
	    ;;
	mttb)
	    arg_type="Matrix"
	    arg_size="(MTTNX,MTTNU)"
	    ;;
	mttc)
	    arg_type="Matrix"
	    arg_size="(MTTNY,MTTNX)"
	    ;;
	mttd)
	    arg_type="Matrix"
	    arg_size="(MTTNY,MTTNU)"
	    ;;
	mttax | mttdx | mttedx | mttx | mttopen)
	    arg_type="ColumnVector"
	    arg_size="(MTTNX)"
	    ;;
	mttpar)
	    arg_type="ColumnVector"
	    arg_size="(MTTNPAR)"
	    ;;
	mttsimpar_map)
	    arg_type="Octave_map"
	    arg_size="";
	    ;;
	mttu)
	    arg_type="ColumnVector"
	    arg_size="(MTTNU)"
	    ;;
	mtty)
	    arg_type="ColumnVector"
	    arg_size="(MTTNY)"
	    ;;
	mttt)
	    arg_type="const double"
	    arg_size=""
	    ;;
	nil)
	    arg_type="void *"
	    arg_size="(0x0)"
	    ;;
	*)
	    echo "Argument ${arg} not supported - sorry"; exit 1
    esac
}


get_field ()
{ # parse comma separated string
    s=${1:-""}					# comma separated string
    i=${2:-0}					# field number in string

    if [ 0 -eq ${i} ]; then			# return number of fields
	echo ${s} |\
	awk -F\, '{ print NF }'
    else					# return ith field
	echo ${s} |\
	awk -F\, -v i=${i} '{ print $i }'
    fi
}


get_extra_fields ()
{ # return list of words in s2 and not in s1
    s1=${1:-""}					# comma separated list
    s2=${2:-""}					# comma separated list

    c1=`get_field ${s1} 0`			# count words in s1
    c2=`get_field ${s2} 0`			# count words in s2
	
    ans=""
	
    i2=0					# s2 word index
    while [ ${i2} -lt ${c2} ]; do
        flag=0					# appearance of word in s1 and s2?
	i2=`expr ${i2} + 1`
	w2=`get_field ${s2} ${i2}`		# i2 th word in s2
	i1=0					# s1 word index
	while [ ${i1} -lt ${c1} ]; do
	    i1=`expr ${i1} + 1`
	    w1=`get_field ${s1} ${i1}`		# i1 th word in s1
	    if [ ${w2} = ${w1} ]; then
		flag=1				# w2 occurs in s1
	    fi
        done
	if [ ${flag} -eq 0 ]; then		# w2 is not in s1?
	    if [ -z ${ans:-""} ]; then		#  string is empty?
		ans=${w2}			#   assign w2
	    else
		ans=${ans},${w2}		#   append w2
	    fi
        fi
    done
    echo ${ans}
}


write_DLD_header()
{
    cat <<EOF
#ifndef STANDALONE
#include <octave/oct.h>
#include <octave/ov-struct.h>
#include <octave/toplev.h>
#include <math.h>
#include "useful-functions.hh"
#include "${system}_cr.h"
#include "${system}_def.h"
#include "${system}_sympar.h"

DEFUN_DLD (${system}_${rep}, args, ,
"Usage: [$output] = ${system}_${rep}($args)
Octave ${rep} representation of system ${system}
Generated by MTT on `date`")
{

  octave_value_list retval;
#endif // ! STANDALONE

EOF
}


map_DLD_inputs ()
{
    s=${1:-""}					# comma separated input list
    if [ -z ${s:-""} ];then return; fi
    printf "#ifndef STANDALONE\n"
    c=`get_field ${s} 0`			# count of inputs
    i=0
    printf "  if (${c} != args.length ()) usage (\"${fun_name} expected ${c} argument(s): ${s}\");\n\n"
    while [ ${i} -lt ${c} ]; do
	j=${i}
	i=`expr ${i} + 1`
	w=`get_field ${s} ${i}`		# argument name
	get_arg_specific_stuff ${w}
	case ${arg_type} in
	    "const double")
		printf "  ${arg_type}\t${w}\t= args(${j}).double_value ();\n"
		;;
	    ColumnVector | Matrix | *)
		printf "  ${arg_type}\t${w}\t= args(${j}).%s ();\n" ${vector_value}
		;;
	esac
    done
    printf "#endif // ! STANDALONE\n\n"
}	


declare_DLD_outputs ()
{
    s=${1:-""}					# comma separated output list
    c=`get_field ${s} 0`			# count of outputs
    i=0
    while [ ${i} -lt ${c} ]; do
	i=`expr ${i} + 1`
	w=`get_field ${s} ${i}`		# argument name
	get_arg_specific_stuff ${w}
	printf "  ${arg_type}\t${w}\t${arg_size};\n"
    done
}


return_DLD_outputs ()
{
    s=${1:-""}					# comma separated output list
    c=`get_field ${s} 0`			# count of outputs
    i=0
    cat <<EOF

\/\/ END Code

#ifndef STANDALONE
EOF
    while [ ${i} -lt ${c} ]; do
	j=${i}
	i=`expr ${i} + 1`
	w=`get_field ${s} ${i}`
	printf "  retval (${j})\t= octave_value (${w});\n"
    done
    cat <<EOF
  return (retval);
}
#endif // ! STANDALONE
EOF
}

write_standalone_header ()
{
    get_arg_specific_stuff ${output}
    cat <<EOF

#ifdef STANDALONE
#include <octave/oct.h>
#include <octave/ov-struct.h>
#include "useful-functions.hh"
#include "${system}_cr.h"
#include "${system}_def.h"
#include "${system}_sympar.h"

${arg_type} F${system}_${rep} (
EOF
    if [ -z ${args:-""} ]; then
	printf "\tvoid"
    else
	c=`get_field ${args:-""} 0`
	i=0
	while [ ${i} -lt ${c} ]; do
	    i=`expr ${i} + 1`
	    if [ ${i} -lt ${c} ]; then
		comma=","
	    else
		comma=""
	    fi
	    w=`get_field ${args} ${i}`
	    get_arg_specific_stuff ${w}
	    printf "\t${arg_type}\t&${w}${comma}\n"
	done
    fi
    cat <<EOF
)
{
#endif // STANDALONE
EOF
}

return_standalone_output ()
{
    cat <<EOF
#ifdef STANDALONE
  return ${output};
}
#endif // STANDALONE
EOF
}

# Header information
cat<<EOF
$modeline
$function $declaration
$Lc $declaration
$Lc System $system, representation $rep, language $language; $Rc
$Lc File $1_$rep.$language; $Rc
$Lc Generated by MTT on `date`; $Rc
EOF

if [ ${language} = "oct" ];then
    write_standalone_header
    write_DLD_header
    map_DLD_inputs ${args}
    undeclared=`get_extra_fields ${args:-"nil"} ${output:-"nil"}`
    declare_DLD_outputs ${undeclared}
    array2constant
 	case ${arg_type} in
 	    Matrix)
 		printf "  ${w}\t\t\t= zeros ${arg_size};\n"
 		;;
 	    *)
 		;;
 	esac

    cat <<EOF

// BEGIN Code

EOF
    return_DLD_outputs ${output}
    return_standalone_output
else

if [ -n "$noglobals" ]; then
cat<<EOF

## Horrible fudge to make mtt_m2p work
global ...
mtt_no_globals ;
EOF
fi

## Arrays 
array2constant

# Mark start of code
echo
echo $start

fi


MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]