#!/usr/bin/ksh93
################################################################
#### Program: cut_k93
#### 
#### Description: Emulation of the Unix "cut" cutand
#### 
#### Author: Dana French (dfrench@mtxia.com)
####         Copyright 2004
#### 
#### Date: 07/22/2004
#### 
################################################################
function cut_k93 {
  typeset TRUE="0"
  typeset FALSE="1"
  typeset CUTCOLS="${FALSE}"
  typeset CUTFLDS="${FALSE}"
  typeset VERBOSE="${FALSE}"
  typeset VERYVERB="${FALSE}"
  typeset DELIM="${IFS}"
  typeset LINE
  typeset FLDS
  typeset COLS
  typeset BEGIN
  typeset END
  typeset IDX
  typeset NEWLINE
  typeset FNAME

  while getopts ":d:c:f:vV" OPTION
  do
    case "${OPTION}" in
        'd') DELIM="${OPTARG}";;
        'c') COLS="${OPTARG}"
             CUTCOLS="${TRUE}";;
        'f') FLDS="${OPTARG}"
             CUTFLDS="${TRUE}";;
        'v') VERBOSE="${TRUE}";;
        'V') VERYVERB="${TRUE}";;
        '?') print "Syntax: cut_k93 [-d delim] [-c 0-9] [-f 0-9] file ..." && exit 1 ;;
    esac
  done
 
  shift $(( ${OPTIND} - 1 ))

  if (( CUTCOLS == TRUE && CUTFLDS == TRUE ))
  then
    print "ERROR: You may specify '-c' OR '-f' but not both."
    exit 4
  fi

  typeset STDIN="${1:+${FALSE}}"
  STDIN="${STDIN:-${TRUE}}"

#### Read in the data either from STDIN or one or more files
  if (( STDIN == TRUE ))
  then
      (( CUTCOLS == TRUE )) && cutcols_k93 "${COLS}"
      (( CUTFLDS == TRUE )) && cutflds_k93 "${FLDS}" "${DELIM}"
  else
      for FNAME in "${@}"
      do
          exec 0<"${FNAME}"
            (( CUTCOLS == TRUE )) && cutcols_k93 "${COLS}"
            (( CUTFLDS == TRUE )) && cutflds_k93 "${FLDS}" "${DELIM}"
          exec 0<&-
      done
  fi

  return 0
}
################################################################
function cutcols_k93 {
    typeset COLS="${1}"
    typeset LINE
    typeset COLS
    typeset BEGIN
    typeset END

    while read -r -- LINE
    do
        IFS="${IFS},"
        for CUT in ${COLS}
        do
          BEGIN="${CUT}"
          END="1"
          [[ "${CUT//-/_}" = *_* ]] && BEGIN="${CUT%%-*}" && END="${CUT##*-}"
          [[ "${CUT//-/_}" = *_* ]] && (( END = END - BEGIN + 1 ))
          (( BEGIN-- ))
          print -r -n -- "${LINE:BEGIN:END}"
        done
        print
    done
}
################################################################
function cutflds_k93 {
    typeset FLDS="${1}"
    typeset DELIM="${2}"
    typeset TRUE="0"
    typeset FALSE="1"
    typeset NEWLINE="${TRUE}"
    typeset LINE
    typeset FLDS
    typeset BEGIN
    typeset END
    typeset IDX

    while IFS="${DELIM}" read -r -A -- LINE
    do
        IFS=$', \t\n'
        for CUT in ${FLDS}
        do
          BEGIN="${CUT}"
          END="${BEGIN}"
          [[ "${CUT//-/_}" = *_* ]] && BEGIN="${CUT%%-*}" && END="${CUT##*-}"
          (( BEGIN-- ))
          (( END-- ))
          for (( IDX=BEGIN; IDX<=END; ++IDX ))
          do
            (( NEWLINE == FALSE )) && print -r -n -- "${DELIM:0:1}"
            print -r -n -- "${LINE[${IDX}]}"
            NEWLINE="${FALSE}"
          done
        done
        print
        NEWLINE="${TRUE}"
        unset LINE
    done
}
################################################################

cut_k93 "${@}"