#!/bin/sh
VERSION=2.2.2
NAME=`basename $0`
NV="$NAME $VERSION: print a series of integers, floats, or function values"
LICENSE="Copyright (C) 2006, 2007, 2009, 2011-2013 Dimitar Ivanov

License: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law."

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

ofmt="%.6g"
sep=`echo |awk '{printf( "%080d", 0 )}' |tr 0 -`

show_help()
{
  cat << EOH && exit
$sep
$NV
$sep

Usage: $NAME <begin> <end> [<step>] [<func>] [<print_fmt>]
   or: $NAME <number>

Examples:

   a) $NAME 100

   b) $NAME 10 1 -1

   c) $NAME 1 10 0.1 x "N=%05.2f"

   d) $NAME -3.14 3.14 0.01 "sin(x)" "sin(x)=%f at x=%f" 

   e) $NAME -3.14 3.14 0.01 "cos(x*x)" "%g %g" 

Remark: an user-defined function should have syntax conforming to 'awk'.

EOH
}

show_version()
{
  cat << !ver && exit
$NAME $VERSION
$LICENSE
!ver
}

case $1 in
         -h|"") show_help
             ;;
        --help) sep=""
                NV="$NAME produces a series of integers, floats, or function values"
                show_help
             ;;
     --version) show_version
             ;;
            -[-a-zA-Z]*) exec 1>&2
                echo "$NAME: invalid option '$1'"
                echo "Try \`$NAME -h' for help."
                exit 2
             ;;
esac

case $# in
     1) b=0;  e=$1; d=1;
     ;;
     2) b=$1; e=$2; d=1;
     ;;
     3) b=$1; e=$2; d=$3;
     ;;
     4) b=$1; e=$2; d=$3; func=$4;
     ;;
     5) b=$1; e=$2; d=$3; func=$4; ofmt=$5;
     ;;
     *) exit 1
     ;;
esac

[ "$func" ] || func=x;

sign=`echo $d \
      |awk 'BEGIN { if( $1 == 0 ) exit }
            { 
              if( $1 > 0 ) printf "+"
              if( $1 < 0 ) printf "-"
            }'
`
case $sign in
           +) cop='<='
           ;;
           -) cop='>='
           ;;
           *) echo "($NAME) error: step must be different than zero"; exit 2
           ;;
esac

              # Use e1 because of round-off errors with floating numbers
echo |awk "BEGIN \
           {
             CONVFMT = \"%.17g\"
             OFMT = \"%.17g\"
             e1 = $e + ($d/10)
           }
           MAIN
           { 
             i = $b
             while( i ${cop} e1 )
             {
               x = i;
               printf( \"$ofmt\n\", $func, x )
               i = i + ($d)
             }
           }"
