#!/usr/bin/ksh93
################################################################
#### Program: comm_k93
#### 
#### Description: Emulation of the Unix "comm" command
#### 
#### Author: Dana French (dfrench@mtxia.com)
####         Copyright 2004
#### 
#### Date: 07/22/2004
#### 
################################################################
function comm_k93 {
  typeset TRUE="0"
  typeset FALSE="1"
  typeset COL1="${TRUE}"
  typeset COL2="${TRUE}"
  typeset COL3="${TRUE}"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset OPTION
  typeset ARRY1
  typeset ARRY2
  typeset ARRY3
  typeset L1
  typeset L2
  typeset LINE1
  typeset LINE2
  typeset i
  typeset j
  typeset IDX
  typeset OUT

  while getopts ":123vV" OPTION
  do
    case "${OPTION}" in
        '1') COL1="${FALSE}";;
        '2') COL2="${FALSE}";;
        '3') COL3="${FALSE}";;
        'v') VERBOSE="${TRUE}";;
        'V') VERYVERB="${TRUE}";;
        '?') print "Syntax: comm_k93 [-123] [-] file ..." && exit 1 ;;
    esac
  done
 
  shift $(( ${OPTIND} - 1 ))
  typeset FILE1="${1:?ERROR: First File not specified}"
  typeset FILE2="${2:?ERROR: Second File not specified}"

  typeset STDIN1="${FALSE}"
  typeset UNIT1="3"
  if [[ "_${FILE1}" = '_-' ]]
  then
    STDIN1="${TRUE}"
    UNIT1="0"
  fi

  typeset STDIN2="${FALSE}"
  typeset UNIT2="4"
  if [[ "_${FILE2}" = '_-' ]]
  then
    STDIN2="${TRUE}"
    UNIT2="0"
  fi

  (( STDIN1 == TRUE && STDIN2 == TRUE )) &&
    print "ERROR: Only one file may be read from STDIN" &&
    exit 2

  IFS=""

  (( STDIN1 == FALSE )) && eval exec ${UNIT1}\<"${FILE1}"
  typeset CNT1="0"
  while read -u ${UNIT1} -r -- LINE1
  do
    ARRY1[${CNT1}]="${LINE1}"
    IDX[${CNT1}]="${TRUE}"
    (( CNT1++ ))
  done
  (( STDIN2 == FALSE )) && eval exec ${UNIT1}\<\&-

  (( STDIN2 == FALSE )) && eval exec ${UNIT2}\<"${FILE2}"
  typeset CNT2="${CNT1}"
  while read -u ${UNIT2} -r -- LINE2
  do
    ARRY2[${CNT2}]="${LINE2}"
    IDX[${CNT2}]="${TRUE}"
    (( CNT2++ ))
  done
  (( STDIN2 == FALSE )) && eval exec ${UNIT2}\<\&-

  for L1 in "${!ARRY1[@]}"
  do
    for L2 in "${!ARRY2[@]}"
    do
      if [[ "_${ARRY1[${L1}]}" = "_${ARRY2[${L2}]}" ]]
      then
        ARRY3[${L1}]="${ARRY2[${L2}]}"
        unset ARRY2[${L2}]
        unset ARRY1[${L1}]
        unset IDX[${L2}]
      fi
    done
  done

#   for j in "${!ARRY1[@]}" "${!ARRY2[@]}" "${!ARRY3[@]}"
#   do
#     IDX[${j}]="${TRUE}"
#   done

  for i in "${!IDX[@]}"
  do
    (( COL1 == TRUE && COL2 == TRUE && COL3 == TRUE )) &&
        OUT="${ARRY1[${i}]}	${ARRY2[${i}]}	${ARRY3[${i}]}"

    (( COL1 == TRUE  && COL2 == TRUE  && COL3 == FALSE )) &&
        OUT="${ARRY1[${i}]}	${ARRY2[${i}]}"

    (( COL1 == TRUE  && COL2 == FALSE && COL3 == FALSE )) &&
        OUT="${ARRY1[${i}]}"

    (( COL1 == FALSE && COL2 == TRUE  && COL3 == FALSE )) &&
        OUT="${ARRY2[${i}]}"

    (( COL1 == TRUE  && COL2 == FALSE && COL3 == TRUE )) &&
        OUT="${ARRY1[${i}]}	${ARRY3[${i}]}"

    (( COL1 == FALSE && COL2 == FALSE && COL3 == TRUE )) &&
        OUT="${ARRY3[${i}]}"

    (( COL1 == FALSE && COL2 == TRUE  && COL3 == TRUE )) &&
        OUT="${ARRY2[${i}]}	${ARRY3[${i}]}"

    [[ "${OUT}" = *[!$'\t']* ]] && print "${OUT}"

  done
}
################################################################

comm_k93 "${@}"