#!/bin/sh
#
# Script to configure "staticability" of plugins
# author: pancake // nopcode
# update: 2010-01-14
#

LANG=C
LC_ALL=C
LOADLIBS=1

export LANG
export LC_ALL

list () {
  for a in $STATIC ; do echo "static  $a" ; done
  for a in $SHARED ; do echo "shared  $a" ; done
  exit 0
}

help () {
  echo "Usage: ./configure-plugins [options]"
  echo "  -n                   do nothing.. do not generate any file"
  echo "  --list               list all static and shared plugins"
  echo "  --rm-static [dir]    remove plugins that are already in core from dir"
  echo "  --static [name ..]   define named plugin as static"
  echo "  --shared [name ..]   define named plugin as shared"
  echo "  --help, -h           display this helpful message"
  echo "NOTE: static plugins are compiled inside the owner library"
  exit 0
}

cfg=./plugins.cfg

if [ ! -f "$cfg" ]; then
  cp -f ./plugins.def.cfg plugins.cfg
fi

load () {
  if [ -e $cfg ]; then 
    echo "configure-plugins: Loading $cfg .."
    . $cfg
  else
    echo "configure-plugins: Loading $1 .."
    . "$1" #plugins.def.cfg
  fi
}

save () {
  cp $cfg plugins.cfg
 # echo "STATIC=\"$STATIC\"" > $cfg
 # echo "SHARED=\"$SHARED\"" >>$cfg
}

generate_configh () {
  plugins=""
  oldlib=""
  for a in ${STATIC} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      [ -n "$oldlib" ] && echo "     0"
      oldlib=$lib
      if type perl > /dev/null 2>&1 ; then
        uclib=$(echo $lib | perl -pe 'tr/[a-z]/[A-Z]/')
      else
        uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      fi
      echo
      echo "#define R_${uclib}_STATIC_PLUGINS \\"
      plugins="${plugins} __${uclib}"
    fi
    echo "     &r_${lib}_plugin_${plg}, \\"
  done
  [ -n "$oldlib" ] && echo "     0"

  # FILL EMPTY PLUGIN ARRAYS WITH LOVE
  for a in ${SHARED} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      oldlib=$lib
      if type perl > /dev/null 2>&1; then
        uclib=$(echo $lib | perl -pe 'tr/[a-z]/[A-Z]/')
      else
        uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      fi
      if [ -z "`echo ${plugins} | grep __${uclib}`" ]; then
        plugins="${plugins} __${uclib}"
        echo
        echo "#define R_${uclib}_STATIC_PLUGINS 0"
      fi
    fi
  done
}

generate_configmk () {
  plugins=""
  oldlib=""
  for a in ${STATIC} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    plg=$(echo $a | cut -d . -f 2) # plugin name
    if [ ! "$oldlib" = "$lib" ]; then
      [ -n "$oldlib" ] && printf "\n"
      oldlib=$lib
      if type perl > /dev/null 2>&1 ; then
        uclib=$(echo $lib | perl -pe 'tr/[a-z]/[A-Z]/')
      else
        uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
      fi
      printf "STATIC_${uclib}_PLUGINS= "
      plugins="${plugins} __${uclib}"
    fi
    printf "p/${plg}.mk "
  done

  echo

  # fill the holes with love
  for a in ${SHARED} ; do
    lib=$(echo $a | cut -d . -f 1) # library
    if type perl > /dev/null 2>&1 ; then
      uclib=$(echo $lib | perl -pe 'tr/[a-z]/[A-Z]/')
    else
      uclib=$(echo $lib | tr '[a-z]' '[A-Z]')
    fi
    if [ -z "`echo ${plugins} | grep __${uclib}`" ]; then
      plugins="${plugins} __${uclib}"
      echo "STATIC_${uclib}_PLUGINS="
    fi
  done
}

generate () {
  echo "configure-plugins: Generating libr/config.h .."
  cat libr/config.h.head > libr/config.h
  echo "#define R2_LOADLIBS ${LOADLIBS}" >> libr/config.h
  generate_configh >> libr/config.h
  cat libr/config.h.tail >> libr/config.h

  echo "configure-plugins: Generating libr/config.mk .."
  cat libr/config.mk.head > libr/config.mk
  generate_configmk >> libr/config.mk
  cat libr/config.mk.tail >> libr/config.mk
  return
}

add () {
  for a in $1 ; do [ $a = $2 ] && return ; done ; echo $1 $2
}

sub () {
  n="" ; for a in $1 ; do [ $a = $2 ] && continue ; n="$n $a" ; done ; echo $n
}


echo | sort -t. > /dev/null 2>&1
if [ $? = 0 ]; then
  SORT="sort -t."
else
  SORT="sort"
fi

dosort () {
  ( for a in $1 ; do echo $a ; done ) | tr _ Z | ${SORT} | tr Z _
  #( for a in $1 ; do echo $a ; done ) | sort -t. --key=1,1d
}

sort_vars () {
  STATIC=$(dosort "$STATIC")
  SHARED=$(dosort "$SHARED")
}

make_static () {
  STATIC=$(add "$STATIC" $1)
  SHARED=$(sub "$SHARED" $1)
}

make_shared () {
  SHARED=$(add "$SHARED" $1)
  STATIC=$(sub "$STATIC" $1)
}

make_ () { : ; }


MODE=""
DONOTHING=0
DEFCFG=./plugins.def.cfg

rmstatic() {
  C=0
  if [ -z "$1" ]; then
    echo "Missing argument"
    exit 1
  fi
  for a in ${STATIC} ; do
    b="`echo $a | tr . _`"
    for ext in dll dylib so ; do
      f="$b.$ext"
      if [ -f "$f" ]; then
        C=$(($C+1))
	printf "  $C found\r"
        #echo "rm -f $f"
        rm -f "$f"
      fi
    done
  done
  echo "Removed $C shared plugins that are already static"
}

RMSTATIC=-

while : ; do
  [ -z "$1" ] && break
  case "$1" in
  "--static") MODE=static ; ;;
  "--shared") MODE=shared ; ;;
  "--without-gpl") DEFCFG=./plugins.nogpl.cfg ;;
  "--disable-loadlibs") LOADLIBS=0 ;;
  "--rm-static") RMSTATIC="$2" ; ;;
  "--list") sort_vars ; list ; ;;
  "-n") DONOTHING=1 ; ;;
  "-h"|"--help") help ; ;;
  *) eval make_$MODE $1 ; ;;
  esac
  shift
done

load ${DEFCFG}
sort_vars

if [ - != "${RMSTATIC}" ]; then
  if [ -z "${RMSTATIC}" ]; then
    echo "Missing argument" >&2
    exit
  fi
  if [ -d "${RMSTATIC}" ]; then
    cd "${RMSTATIC}" && rmstatic "${RMSTATIC}"
  fi
  exit 0
fi

[ ${DONOTHING} = 0 ] && generate

echo SHARED: ${SHARED}
echo STATIC: ${STATIC}

save

exit 0
