#!/bin/sh
#
# A build system for libfndn.
# Written in Shell Script by Stone Horse for systems without libfndn
# installed. Public domain

path() {
  system=`uname -s`

  if test -z $prefix
    then
      if test $system = NetBSD
        then prefix=/usr/pkg
      else
        prefix=/usr
      fi
  fi
}

machine() {
  if test -z $ARCH
    then
      if which arch > /dev/null 2>&1
        then ARCH=`arch`
      else
        ARCH=`uname -m`
      fi
      if test $ARCH != i86
        then
          ARCH=`echo $ARCH | sed -e "s/i[4-9]86/i386/" \
          -e "s/armv[3-6].*/arm/" \
          -e "s/armv7.*/armv7/" \
          -e "s/evbarm/arm/"`
      fi
  fi
  if test $ARCH = arm
    then ASFLAGS="-I arch/arm --warn -march=armv3"
  elif test $ARCH = armv7
    then
      ASFLAGS="--defsym ARM_V7=1 -I arch/arm -march=armv4t"
      ARCH=arm
  elif test $ARCH = i386
    then ASFLAGS="--warn -march=i386"
  elif test "$ARCH" != i86
    then echo Error: unknown architecture. Please fix redo.sh >&2
    echo Abort.
    exit 0
  fi
}

file_state() {
  meta_file=.redo/`echo "$1" | tr "/" "+"`

  if test $system = NetBSD
    then timestamp=`stat -f %m "$1"`
  elif test $system = Minix
    then timestamp=`stat -mtime "$1"`
  else
    timestamp=`stat -c %Y "$1"`
  fi

  if test -f $meta_file
    then
      old_timestamp=`head -1 $meta_file`

      if test $timestamp -eq $old_timestamp
        then return 0
      fi
      old_hash=`tail -n 1 $meta_file`

      hash=`cksum "$1" | cut -f 1 -d " "`
      if test $hash = $old_hash
        then return 0
      fi
  else
    hash=`cksum "$1" | cut -f 1 -d " "`
  fi
  printf "%s\n%s\n" $timestamp $hash > $meta_file
  return 1
}

run() {
  echo "$*"
  "$@" > /dev/null
}

build() {
  system=`uname -s`
  mkdir -p arch/${ARCH}/.redo
  if test $system = NetBSD
    then ASFLAGS="--defsym NetBSD=1 $ASFLAGS"
  fi

  chdir arch/${ARCH}
  for source in *.s
  do
    file_state $source
    if test $? -ne 0
      then
        out=`echo $source | sed -e "s/\.s/\.o/"`
        run "$AS" $ASFLAGS -o $out $source
    fi
  done
  chdir ../..

  mv -f arch/${ARCH}/start.o .
  run "$AR" $ARFLAGS libfndn.a arch/${ARCH}/*.o
}

clean() {
run rm -fr \
arch/${ARCH}/*.o \
libfndn.a \
start.o \
arch/${ARCH}/.redo
}

distclean() {
  clean
  run rm -f .config
}

install() {
  path
  test -f libfndn.a || build
  run mkdir -p ${prefix}/lib ${prefix}/share/doc/libfndn

  run cp -f README ${prefix}/share/doc/libfndn/
  run rm -fr ${prefix}/include/libfndn
  run cp -fr include ${prefix}/include/libfndn
  run cp -f start.o libfndn.a ${prefix}/lib/
}

uninstall() {
  path
  run rm -fr \
${prefix}/include/libfndn \
${prefix}/lib/libfndn.a \
${prefix}/lib/start.o \
${prefix}/share/doc/libfndn
}

defconfig() {
  machine
  path
  echo \# Automatically generated configuration for redo.sh > .config
  if test $system = Minix
    then
      echo AR=\"/usr/minixbcc/0/cr\" >> .config
      echo ARFLAGS=\"-o\" >> .config
      echo AS=\"/usr/minixbcc/0/as\" >> .config
  else
    echo AR=\"ar\" >> .config
    echo ARFLAGS=\"cr\" >> .config
    echo AS=\"as\" >> .config
  fi
  echo ARCH=\"${ARCH}\" >> .config
  echo ASFLAGS=\"${ASFLAGS}\" >> .config
  echo PREFIX=\"${prefix}\" >> .config
}

if test $# -ne 0 && test $1 = defconfig
  then
    defconfig
    exit $?
fi

test -f .config
if test $? -ne 0
  then
    echo You have not yet configured libfndn! >&2
    echo Please run some configurator \(e.g. \"./redo.sh defconfig\"\) >&2
    exit 0
fi
while read line
do
  eval $line
done < .config

if test $# -eq 0
  then
    build
    exit $?
fi

if test $1 = build || test $1 = clean || test $1 = install \
  || test $1 = uninstall || test $1 = defconfig || test $1 = distclean
  then
    eval $1
else
  echo Error: unknown verb: $1 >&2
  exit 1
fi
