#!/bin/sh
#
# @(#)ICELLS_nelsis3 1.31 03/03/95 Delft University of Technology
#
# ICELLS --- install the cell libraries for Ocean and Nelsis/R3. Create Nelsis
#            projects for users with cell libraries already imported. This
#            script sets up an environment of shell varaibles and shell
#            functions, and then sources a script in the cell library tree.
#            See the function sourceCommandScript() below for details.
#
# Before you can execute this script you'll have to edit the "user customizable
# area" below _OR_ set the following environment variables:
#
# OCEANPROCESS  -- the name of the process to use, e.g. "fishbone"
# OCEANPATH     -- the absolute path to the place where the OCEAN tree lives
# ICDPATH       -- the absolute path to the place where the Nelsis tree lives
# ICDUSER       -- the username of the owner of the nelsis tree
#

##############################################################################
# Interpret the name of the script and the command line arguments

LIBSCRIPT=`basename $0`
ARGUMENT1="$1"
ARGUMENT2="$2"

##############################################################################

##############################################################################
#		 U S E R    C U S T O M I Z A B L E   A R E A		     #
##############################################################################

#
#  !!!!! WARNING--- DO NOT USE SPACES OR TABS AROUND THE EQUAL SIGN '=' !!!!!
#

# The absolute path to the place where the Ocean tree lives.
# Example: OCEAN_TREE=/users/extra/ocean
OCEAN_TREE=/usr/ocean

# The absolute path to the place where the Nelsis tree lives.
# Example: NELSIS_TREE=/users/u5/cacd.sun4
NELSIS_TREE=/usr/cacd

# The login name of the user who owns the nelsis tree. Don't make this root!
# Example: NELSIS_OWNER=cacd
NELSIS_OWNER=cacd

# the default image that we use. Choose from "fishbone", "octagon" or
# "gatearray":
DEFAULT_PROCESS=fishbone

##############################################################################
#	  E N D   O F   U S E R    C U S T O M I Z A B L E   A R E A	     #
#									     #
#				     * * *				     #
#									     #
#	   D O N 'T    C H A N G E   B E L O W    T H I S   L I N E	     #
##############################################################################

# if OCEANPATH is set in the environment, it overrides the default:
OCEAN_TREE=${OCEANPATH:-$OCEAN_TREE}

# make sure that OCEANPATH is set in the environment:
OCEANPATH=$OCEAN_TREE ; export OCEANPATH

# if ICDPATH is set in the environment, it overrides the default:
NELSIS_TREE=${ICDPATH:-$NELSIS_TREE}

# if ICDUSER is set in the environment, it overrides the default:
NELSIS_OWNER=${ICDUSER:-$NELSIS_OWNER}

##############################################################################

# the default image/process is fishbone:
if [ "$OCEANPROCESS" = "" ] ; then
   OCEANPROCESS=$DEFAULT_PROCESS
fi

# Make symbolic links under this tree to where the cell libraries really are:
NELSIS_CELLLIBDIR="$NELSIS_TREE/celllibs/$OCEANPROCESS"

# Place where the ascii stuff lives:
OCEAN_ASCIICELLS="$OCEAN_TREE/celllibs/$OCEANPROCESS/src/nelsis3"

# if you already have another meaning for MACHINE, use OCEANMACHINE instead:
if [ "$OCEANMACHINE" != "" ] ; then
   MACHINE="$OCEANMACHINE" ; export MACHINE
fi

if [ "$MACHINE" = "" ] ; then
   echo "You'll have to set the environment variable MACHINE first..."
   echo "This variable reflects the computer architecture that you are"
   echo "currently running this program on."
   exit 1
fi

# Place where the cell libraries live:
OCEAN_CELLLIBDIR="$OCEAN_TREE/celllibs/$OCEANPROCESS/${MACHINE}/nelsis3"

##############################################################################

# on the bloody Sun we get a broken "echo" if we don't do this:
PATH=/usr/5bin:$PATH

# just to make sure we can find the OCEAN and Nelsis tools:
PATH=${NELSIS_TREE}/bin:${PATH}
PATH=${NELSIS_TREE}/bin/${MACHINE}:${PATH}
PATH=${OCEAN_TREE}/bin:${PATH}
PATH=${OCEAN_TREE}/bin/${MACHINE}:${PATH}
PATH=${OCEAN_TREE}/bin/${MACHINE}/nelsis3:${PATH}

if [ ! -d $NELSIS_TREE/bin ] ; then
   echo "ERROR: Where is the Nelsis bin directory?"
   echo "       Not in $NELSIS_TREE/bin ..."
   exit 1
fi

if [ ! -d $OCEAN_TREE/bin ] ; then
   echo "ERROR: Where is the OCEAN bin directory? "
   echo "       Not in $OCEAN_TREE/bin ..."
   exit 1
fi


testInput()
{
   ERRORS=0
   if [ ! -d "$OCEAN_TREE" ] ; then
      echo The Ocean tree \"${OCEAN_TREE}\" is not an existing directory
      ERRORS=`expr $ERRORS + 1`
   fi
   if [ ! -d "$NELSIS_TREE" ] ; then
      echo The Nelsis tree \"${NELSIS_TREE}\" is not an existing directory
      ERRORS=`expr $ERRORS + 1`
   fi
   NELSIS_GECOS=`awk -F: "/^${NELSIS_OWNER}:/{print \\$5}" /etc/passwd`
   if [ $ERRORS -gt 0 ] ; then
      echo ''
      echo $ERRORS errors detected in the input specification ...
      echo ''
      echo You may need to edit the 'user customizable area' at the top
      echo of the script \"$0\".
      exit 1
   fi
}

##############################################################################

# Make all the symbolic links that are necessary to run Ocean:
makeLinks()
{
   if [ ! -d `dirname "$NELSIS_CELLLIBDIR"` ] ; then
      mkdir `dirname "$NELSIS_CELLLIBDIR"` || exit 1
   fi
   makeLink "$OCEAN_CELLLIBDIR" "$NELSIS_CELLLIBDIR" 
}

##############################################################################

# this essentially does an "ls -s argv[1] argv[2]" with some error checking
makeLink()
{
   if [ ! -r "$1" ] ; then
      echo \"$1\" does not exist or is not readable. Stop.
      exit 1
   fi
   if [ -h "$2" ] ; then
      OLD_POINTED_TO=`ls -l "$2" | awk '{print $NF}'`
      if [ "$OLD_POINTED_TO" = "$1" ] ; then
         return                # link already exists
      else
	 rm -f "$2" || exit 1  # link exists but points to wrong place
      fi
   fi
   ln -s "$1" "$2" || exit 1
}

##############################################################################

# Read commands from the script $OCEAN_ASCIICELLS/../$LIBSCRIPT and execute
# them. The script can call any function defined in ICELLS. In addition, it
# can assume that the following shell variables have been set:
#
#     $PROJECT  (the full path name of the project to be created)
#     $BINLIBS  (the full path to the directory containing the
#                binary version of the libraries)
#     $SRCLIBS  (the full path to the directory containing the ascii version
#                of the libraries, as well as the template directory)
#
# Useful functions to call from $LIBSCRIPT are:
#
# To compile cell library "primitives" and install it under the $BINLIBS tree:
#     checkOrCreateProject     $BINLIBS/primitives
#     cp $SRCLIBS/primitives/* $BINLIBS/primitives
#     installCellLibrary       $BINLIBS/primitives
#     runProgramInLib $BINLIBS/primitives gnarp -CFb primitives mkLibprim
#
# To compile cell library "oplib" and install it under the $BINLIBS tree:
#     checkOrCreateProject     $BINLIBS/oplib # no complaints if already exists
#     cp $SRCLIBS/primitives/* $BINLIBS/oplib
#     importCellLibrary        $BINLIBS/oplib $BINLIBS/primitives
#     installCellLibrary       $BINLIBS/oplib
#
# To create a project with pre-imported libraries "primitives" and "oplib":
#     checkAndCreateNewProject $PROJECT # complain badly if something wrong
#     importCellLibrary        $PROJECT $BINLIBS/primitives
#     importCellLibrary        $PROJECT $BINLIBS/oplib
#
sourceCommandScript()
{
   SCRIPT="$OCEAN_ASCIICELLS/../$LIBSCRIPT"
   if [ ! -r "$SCRIPT" ] ; then
      echo "$SCRIPT" does not exist or is not readable ...
      exit 1
   fi
   # source the installation commands. This script could look like this:
   #-------------------------------------------------------------------------
   # #
   # # This file is executed by the ICELLS program to install cell libraries.
   # # Three commands are recognized:
   # #      1. installCellLibrary <libname>
   # #         This creates (if necessary) the project <libname>, compiles
   # #         the layout and circuit into the database and copies all sorts
   # #         of configuration files to <libname>.
   # #      2. importCellLibrary <project> <libname>
   # #         This imports all root cells in <libname> into <project>. If
   # #         <project> does not exist already, it is created.
   # #      3. runProgramInLib <libname> <program> [...program options...]
   # #         This runs the program <program> in the project <libname>.
   # #
   # installCellLibrary    primitives
   # importCellLibrary     oplib1_93      primitives
   # installCellLibrary    oplib1_93
   # installCellLibrary    bonding
   # importCellLibrary     templ1_93      primitives
   # importCellLibrary     templ1_93      oplib1_93
   # importCellLibrary     templ1_93      bonding
   #-------------------------------------------------------------------------

   SRCLIBS="$OCEAN_ASCIICELLS"
   BINLIBS="$OCEAN_CELLLIBDIR"
   PROJECT="$ARGUMENT1"
   . "$SCRIPT"
}

##############################################################################

# argv[1] is the library
# argv[2] is the program to run in this library
# argv[3, ...] are arguments for the program
runProgramInLib()
{
   thedir=$1
   prog="$2 $3 $4 $5 $6 $7 $8 $9"
   checkOrCreateProject "$thedir"
   if [ "$prog" = "" ] ; then
      echo ERROR: no program specified for runProgramInLib ...
      exit 1
   fi
   (cd $thedir || exit 1
    $prog || exit 1)
}

##############################################################################

# import all cells of project argv[2] into project argv[1]
importCellLibrary()
{
   proj=$1
   libr=$2
   checkOrCreateProject "$proj"
   OLD_DIR=`pwd`
   cd $proj
   CWD=`pwd` ; export CWD                       # required by the nelsis tools
   ICDUSERNAME="$NELSIS_OWNER"; export ICDUSER  # also required by nelsis
   ICDPATH="$NELSIS_TREE"; export ICDPATH       # also required by nelsis
   if [ "$libr" != "" ] ; then
      if grep "^$libr\$" projlist > /dev/null; then
         :
      else
         addproj $libr
      fi
      impcell -c -a $libr
      impcell -l -a $libr
   fi
   cd $OLD_DIR
}

##############################################################################

# Copy the ascii files for project argv[1] from directory argv[2] to directory
# argv[3]/argv[1]. The ascii files are recognized because they all start with
# the name of the project, followed by a dot.
#
# argv[1] is the name of the project;
# argv[2] is the directory where the files are now;
# argv[3] is the directory containing the project
#         where the files must be copied to.
copyDefaultFiles()
{
   for f in $2/$1/.??* $2/$1/*; do
       if [ $f = "$2/$1/.??*" -o $f = "$2/$1/*" ] ; then
	  continue
       fi
       echo cp $f $3/$1
       cp $f $3/$1 || exit 1
   done
}

##############################################################################

checkOrCreateProject()
{
   # make sure that the parent directories exists:
   THEPARENT=`dirname $1`
   if [ ! -d "$THEPARENT" ] ; then        # bash does not like this
      mkdir -p "$THEPARENT" || exit 1
   fi
   if [ ! -d "$1" ] ; then
      case "$OCEANPROCESS" in
         fishbone)  PROCESSID=41 ; PROCESSLAMBDA=0.2 ;;
         octagon)   PROCESSID=40 ; PROCESSLAMBDA=0.1 ;;
         gatearray) PROCESSID=6  ; PROCESSLAMBDA=1.0 ;;
         *) echo "ERROR: I don't know what image you want. All I have is"
	    echo "the environment OCEANPROCESS set to \"$OCEANPROCESS\"."
	    echo "It should be set to either fishbone, octagon or gatearray."
	    exit 1
      esac
      (echo $PROCESSID ; echo $PROCESSLAMBDA) | mkpr "$1" > /dev/null || exit 1
   fi
   if [ ! -f "$1/.dmrc" ] ; then
      echo "$1" exists but is not a project directory ...
      exit 1
   fi
   if [ "`head -1 $1/.dmrc`" != 3 ] ; then
      echo "$1" exists but is not a release 3 project!
      exit 1
   fi
}

##############################################################################

# Exit if there is any reason to not create a new project argv[1].
checkNewProject()
{
   if [ "$1" = "" ] ; then
      echo "ERROR: You forgot to specify a project name ..."
      echo "       Usage: `basename $0` <projectname>"
      exit 1
   fi
   if [ -d $1 -o -f $1 -o -h $1 -o -p $1 -o -c $1 -o -b $1 ] ; then
      echo "ERROR: \"$1\" already exists ..."
      exit 1
   fi
   if [ ! -w `dirname $1` ] ; then
      echo "ERROR: directory \"`dirname $1`\" is not writable,"
      echo "       cannot create \"$1\" ..."
      exit 1
   fi
}

##############################################################################

checkAndCreateNewProject()
{
   checkNewProject $1
   checkOrCreateProject $1
}

##############################################################################


# argv[1] is the directory containing the cell library to install
installCellLibrary()
{
   proj=$1
   checkOrCreateProject "$proj"
   OLD_DIR=`pwd`
   cd $proj
   CWD=`pwd` ; export CWD                       # required by the nelsis tools
   ICDUSERNAME="$NELSIS_OWNER"; export ICDUSER  # also required by nelsis
   ICDPATH="$NELSIS_TREE"; export ICDPATH       # also required by nelsis
   
   if [ -f cells.sls ] ; then
      csls cells.sls	    # compile ascii circuit representation
   fi
   if [ -f cells.ldm ] ; then
      cldm -f cells.ldm	    # compile ascii layout representation
   fi
   rm -f seadif/*.sd?	    # remove all seadif representations
   if [ -f cells.sls -o -f cells.ldm ] ; then
      if [ -f Mapfile ] ; then
         nelsea -m Mapfile     # convert cells in Mapfile from nelsis to seadif
      else
         nelsea		    # convert all cells from nelsis to seadif
      fi
      chmod ugo=r seadif/*.sdf # make the library read-only
      for cell in `cat circuit/celllist`; do
          sls_exp $cell        # make binary expansion for switch level simulator
      done
   fi
   cd $OLD_DIR
}


##############################################################################
#				    M A I N				     #
##############################################################################
testInput
sourceCommandScript
exit 0
##############################################################################
