#!/opt/osstech/bin/ksh
##
## GNU coreutils seq(1) clone
## Copyright (c) 2009 SATOH Fumiyasu @ OSS Technology, Inc.
##               <http://www.osstech.co.jp/>
##
## License: GNU General Public License version 2 or later
## Date: 2009-03-17, since 2009-03-16
##

## ksh emulation by zsh
if type emulate >/dev/null 2>&1; then
  emulate -R ksh
fi

set -u

pdie() { echo "$0: ERROR: $*" 1>&2; exit 1; }

first="1"
step="1"
format=""
separator="
"
equal_width_f=""

cmd_usage="Usage: $0 [OPTIONS] [FIRST [STEP]] LAST"

getopts_want_arg()
{
  if [ $# -lt 2 ]; then
    pdie "Option requires an argument: $1"
  fi
  if [ $# -ge 3 ]; then
    if expr x"$2" : x"$3\$" >/dev/null; then
      : OK
    else
      pdie "Invalid value for option: $1 $2"
    fi
  fi
}

while test "$#" -gt 0; do
  OPT="$1"; shift
  case "$OPT" in
  -f|--format)
    getopts_want_arg "$OPT" ${1+"$1"}
    format="$1"; shift
    ;;
  -s|--separator)
    getopts_want_arg "$OPT" ${1+"$1"}
    separator="$1"; shift
    ;;
  -w|--equal-width)
    equal_width_f="yes"
    ;;
  --)
    break
    ;;
  -[!0-9]*)
    pdie "Invalid option: $OPT"
    exit 1
    ;;
  *)
    set -- "$OPT" ${1+"$@"}
    break
    ;;
  esac
done

case "$#" in
1)
  last="$1"; shift
  ;;
2)
  first="$1"; shift
  last="$1"; shift
  ;;
3)
  first="$1"; shift
  step="$1"; shift
  last="$1"; shift
  ;;
*)
  echo "$cmd_usage"
  exit 1
  ;;
esac

if [ "$step" -ge 0 ]; then
  operator="-gt"
else
  operator="-lt"
fi

## ======================================================================

if [ -z "$format" ]; then
  if [ -z "${first##*.*}" ]; then
    first_precision="${first##*.}"
    first_precision_w="${#first_precision}"
  fi
  if [ -z "${step##*.*}" ]; then
    step_precision="${step##*.}"
    step_precision_w="${#step_precision}"
  fi
  if [ ${first_precision_w-0} -gt ${step_precision_w-0} ]; then
    precision_w="${first_precision_w-0}"
  else
    precision_w="${step_precision_w-0}"
  fi

  if [ -n "$equal_width_f" ]; then
    first_integer="${first%%.*}"
    last_integer="${last%%.*}"
    if [ "${#first_integer}" -gt "${#last_integer}" ]; then
      integer_w="${#first_integer}"
    else
      integer_w="${#last_integer}"
    fi

    if [ "${precision_w-0}" -gt 0 ]; then
      ## "+ 1" for "."
      let "integer_w += ${precision_w} + 1"
    fi
  fi

  format="%${integer_w+0}${integer_w-}.${precision_w-0}f"
fi

## ======================================================================

count=0

while :; do
  let 'current = first + step * count'
  [ "$current" "$operator" "$last" ] && break

  [ "$count" -gt 0 ] && printf '%s' "$separator"
  printf "$format" "$current"

  let 'count += 1'
done

[ "$count" -gt 0 ] && echo

