#!/bin/sh
# 1.Parameter: Makefile-Template
# 2.Parameter: Ausgabedatei
# schreibt Makefile, ersetzt:
#  - ##HDAT## durch H-Dateien
#  - ##ODAT## durch Objekt-Dateien
#  - ##ODEP## <Complier-Anweisung>
#      durch Abhaengigkeiten der Objekt-Dateien fuer Compilierung
#      <Compiler-Anweisung>: alles einschliesslich "-c" ohne C-Datei
#  Beispiel:
#    H_DAT = ##HDAT##
#    OBJ = ##ODAT##
#    ##ODEP## $(CC) $(CFLAGS) -c


# Aufruf: s2hex varname "String"
# setzt Variable varname mit Hex-Umwandlung von "String",
# z.B. String="ABC" => varname="414243"
s2hex() {
  s2h_hex="$1"
  s2h_wert=`$ECHOB "$2$ECHOC" | od -An -txC | sed -e 's/ //g'`
  eval "$s2h_hex"="\"$s2h_wert\""
}

# Aufruf: array_set var_$index "String"
# setzt Variable var_$index fuer beliebigen $index mit Wert="String"
array_set() {
  fs_name="$1"
  fs_wert="\"$2\""
  eval "$fs_name"="$fs_wert"
}

# Aufruf: array_get varname var_$index
# setzt Variable varname mit Wert von Variable var_$index fuer beliebigen $index
array_get() {
  fs_name="$1"
  fs_wert="$2"
  eval $fs_name="`eval echo '\\$$fs_wert'`"
}


# Feld-Ausgabe
arrayausgabe() {
  echo "*** Start ***"
  fnr=0
  while :
  do
    fnr=`expr $fnr + 1`
    array_get vtmp dname_$fnr
    test "$vtmp" = "" && break

    echo "FNR=$fnr:"
    echo "- dname[$fnr]=\"$vtmp\""
    s2hex inr "$vtmp"
    array_get vtmp iname_$inr
    echo "- iname[$inr]=\"$vtmp\""

    array_get vtmp dnamez_$fnr
    echo "- dnamez[$fnr]=\"$vtmp\""

    array_get vtmp fname_$fnr
    echo "- fname[$fnr]=\"$vtmp\""

    array_get vtmp oname_$fnr
    echo "- oname[$fnr]=\"$vtmp\""
  done
  echo "*** End ***"
  echo
}


if test "$1" = "" || test "$2" = "" || test "$1" = "-h" || test "$2" = "-h" || test ! -f "$1"
then
  echo "Usage: $0 <Makefile-Template> <Outputfile>"
  exit 1
fi
makefiletpl="$1"
outputfile="$2"

# echo ohne NL
ECHOB="echo -n"
ECHOC=""
erg=`echo "a\cb"`
test "$erg" = "a" && { ECHOB="echo"; ECHOC="\c"; }

# C-Dateien suchen, die H-Dateien haben
umax=0
cfiles=`ls *.c`
fnr=0
for file in $cfiles
do
  rawfile=`echo $file | sed -e 's/\.c$//'`
  test -f "$rawfile.h" || continue
  fnr=`expr $fnr + 1`
  test `expr $fnr % 5` -eq 0 && $ECHOB ".$ECHOC"
  array_set dname_$fnr "$rawfile"  # gefundene Datei
  array_set fname_$fnr "$rawfile"  # gefundene Datei (fuer oname)
  array_set oname_$fnr "$rawfile.o: $rawfile.c"  # Abhaengigkeiten fuer O-Datei
  for deps in `grep '# *include .*\.h"' $file | sed -e 's%.*\("[^"]*\.h"\).*%\1%' | cut -d\" -f2 | sed -e 's/\.h$//'`
  do
    vz=`dirname "$deps"`
    if test "$vz" != "."
    then
      unr=0
      uverz=""
      while :
      do
        unr=`expr $unr + 1`
        array_get uverz uverz_$unr
        test "$uverz" = "" && break
        test "$uverz" = "$vz" && break
      done
      test "$uverz" = "" && { umax=`expr $umax + 1`; array_set uverz_$umax "$vz"; }
    fi
    if test "$vz" = "." && test "$rawfile" != "$deps" && test -f "$deps.c"
    then
      # iname_<$deps-in-hex> mit $fnr-Liste fuellen
      s2hex inr "$deps"
      array_get iname iname_$inr
      array_set iname_$inr "$iname $fnr"
      # dnamez_$fnr inkrementieren
      array_get dnamez dnamez_$fnr
      test "$dnamez" = "" && dnamez=0
      dnamez=`expr $dnamez + 1`
      array_set dnamez_$fnr "$dnamez"
    fi
    array_get onamez onamez_$fnr
    test "$onamez" = "" && onamez=0
    onamez=`expr $onamez + 1`
    test $onamez -gt 5 && { array_get oname oname_$fnr; array_set oname_$fnr "$oname #"; onamez="1"; }
    array_set onamez_$fnr "$onamez"
    array_get oname oname_$fnr
    array_set oname_$fnr "$oname $deps.h"
  done
done
#arrayausgabe

# Dateien sortieren von allgemein zu speziell
h_files=""
h_filez=0
o_files=""
o_filez=0
while :
do
  fz=0
  fnr=0
  while :
  do
    fnr=`expr $fnr + 1`
    test `expr $fnr % 10` -eq 0 && $ECHOB ".$ECHOC"
    array_get dname dname_$fnr
    test "$dname" = "" && break
    test "$dname" = "?" && continue
    array_get dnamez dnamez_$fnr
    test "$dnamez" = "" && dnamez=0
    test $dnamez -gt 0 && continue

    fz=1
    h_filez=`expr $h_filez + 1`
    test $h_filez -gt 5 && { h_files="$h_files #"; h_filez="1"; }
    test "$h_files" = "" && h_files="$dname.h" || h_files="$h_files $dname.h"
    o_filez=`expr $o_filez + 1`
    test $o_filez -gt 5 && { o_files="$o_files #"; o_filez="1"; }
    test "$o_files" = "" && o_files="$dname.o" || o_files="$o_files $dname.o"
    array_set dname_$fnr "?"

    s2hex inr "$dname"
    array_get iname iname_$inr
    for fn2 in $iname
    do
      array_get dnamez dnamez_$fn2
      test "$dnamez" = "" && dnamez=1
      dnamez=`expr $dnamez - 1`
      array_set dnamez_$fn2 "$dnamez"
    done
    array_set iname_$inr ""
  done
  test $fz -eq 0 && break
done

# falls noch etwas uebrig ist
fnr=0
while :
do
  fnr=`expr $fnr + 1`
  array_get dname dname_$fnr
  test "$dname" = "" && break
  test "$dname" = "?" && continue

  h_filez=`expr $h_filez + 1`
  test $h_filez -gt 5 && { h_files="$h_files #"; h_filez="1"; }
  test "$h_files" = "" && h_files="$dname.h" || h_files="$h_files $dname.h"
  o_filez=`expr $o_filez + 1`
  test $o_filez -gt 5 && { o_files="$o_files #"; o_filez="1"; }
  test "$o_files" = "" && o_files="$dname.o" || o_files="$o_files $dname.o"
done

echo
#echo "H-Files=\"$h_files\""
#echo "O-Files=\"$o_files\""
#$ECHOB "U-DIRs=$ECHOC"; unr=0; while :; do unr=`expr $unr + 1`; array_get uverz uverz_$unr; test "$uverz" = "" && break; $ECHOB " $uverz$ECHOC"; done; echo

lwr="`printf '\\\\'; printf '\n\t'`"

# Ausgabe nach Outputfile
(
  erszln=`(sed -n -e '/##HDAT##/=' <$makefiletpl; sed -n -e '/##ODAT##/=' <$makefiletpl; sed -n -e '/##ODEP##/=' <$makefiletpl; sed -n -e '/##UDIR##/=' <$makefiletpl; sed -n -e '/##UODAT##/=' <$makefiletpl) | sort -n`
  ersvon=1
  for erszl in $erszln
  do
    # vorige Zeilen ausgeben
    ersbis=`expr $erszl - 1`
    test $ersbis -lt $ersvon && continue
    test $ersbis -gt $ersvon && sed -n -e "$ersvon,${ersbis}p" <$makefiletpl
    ersvon=`expr $erszl + 1`

    zeile=`sed -n -e "${erszl}p" <$makefiletpl`

    if echo "$zeile" | fgrep "##HDAT##" >/dev/null
    then
      # H-Dateien sortiert ausgeben
      vnam=`echo "$zeile" | sed -e 's/##HDAT##.*//'`
      $ECHOB "$vnam$ECHOC"
      tnr=0
      while :
      do
        tnr=`expr $tnr + 1`
        zl=`echo "$h_files" | cut -s -d# -f $tnr`
        test "$zl" = "" && test $tnr -eq 1 && $ECHOB "$h_files$ECHOC"
        test "$zl" = "" && break
        test $tnr -eq 1 || $ECHOB "$lwr$ECHOC"
        $ECHOB "$zl$ECHOC"
      done
      echo

    elif echo "$zeile" | fgrep "##ODAT##" >/dev/null
    then
      # O-Dateien sortiert ausgeben
      vnam=`echo "$zeile" | sed -e 's/##ODAT##.*//'`
      $ECHOB "$vnam$ECHOC"
      tnr=0
      while :
      do
        tnr=`expr $tnr + 1`
        zl=`echo "$o_files" | cut -s -d# -f $tnr`
        test "$zl" = "" && test $tnr -eq 1 && $ECHOB "$o_files$ECHOC"
        test "$zl" = "" && break
        test $tnr -eq 1 || $ECHOB "$lwr$ECHOC"
        $ECHOB "$zl$ECHOC"
      done
      echo

    elif echo "$zeile" | fgrep "##ODEP##" >/dev/null
    then
      # Abhaengigkeiten fuer O-Dateien ausgeben
      canw=`echo "$zeile" | sed -e 's/.*##ODEP## *//'`
      fnr=0
      while :
      do
        fnr=`expr $fnr + 1`
        array_get oname oname_$fnr
        test "$oname" = "" && break
        tnr=0
        while :
        do
          tnr=`expr $tnr + 1`
          zl=`echo "$oname" | cut -s -d# -f $tnr`
          test "$zl" = "" && test $tnr -eq 1 && $ECHOB "$oname$ECHOC"
          test "$zl" = "" && break
          test $tnr -eq 1 || $ECHOB "$lwr$ECHOC"
          $ECHOB "$zl$ECHOC"
        done
        echo
        array_get fname fname_$fnr
        printf "\t"
        echo "$canw ${fname}.c"
        echo
      done

    elif echo "$zeile" | fgrep "##UDIR##" >/dev/null
    then
      # Unterverzeichnisse ausgeben
      vnam=`echo "$zeile" | sed -e 's/##UDIR##.*//'`
      $ECHOB "$vnam$ECHOC"
      tnr=0
      while :
      do
        tnr=`expr $tnr + 1`
        array_get uverz uverz_$tnr
        test "$uverz" = "" && break
        $ECHOB " $uverz$ECHOC"
      done
      echo

    elif echo "$zeile" | fgrep "##UODAT##" >/dev/null
    then
      # Unterverzeichnisse-Object-Dateien ausgeben
      vnam=`echo "$zeile" | sed -e 's/##UODAT##.*//'`
      $ECHOB "$vnam$ECHOC"
      tnr=0
      while :
      do
        tnr=`expr $tnr + 1`
        array_get uverz uverz_$tnr
        test "$uverz" = "" && break
        $ECHOB " $uverz/*.o$ECHOC"
      done
      echo
    fi
  done
  # restliche Zeilen ausgeben
  sed -n -e "$ersvon,\$p" <$makefiletpl
) >$outputfile

exit 0
