#!/bin/sh

#--------------------------------------------------------------------------

# disable glob expansion:
# - this is essential now with perl code inlining into
#   this .sh script:
set -f

ProgramName=`basename "$0" .sh`
ProgramVersionString="0.04.0001 (2007-03-30)"

#--------------------------------------------------------------------------

# replace symbol 'x' with '*' (so 'x' can be used to 
# instead of '*' as multiplication symbol:

#--------------------------------------------------------------------------
# minimal, initial version (could compete in a
# smallest-still-useful-program contest!)
#
#   Temp=`echo "$@" | sed "s, x, *,g"`
#   perl -e "print \"$Temp = \" . ($Temp); print \"\n\""
#--------------------------------------------------------------------------

if [ "$1" == "--help" -o "$1" == "--man" -o "$1" == "--manual" ] ; then
    echo "DESCRIPTION "
    echo "    Small, simple command line based calculator with history (provided "
    echo "    by bash), complex expression evaluation (provided by perl)"
    echo "    and optional bin/oct/dec/hex formatting (provided by perl)."
    echo ""
    echo "USAGE "
    echo "    $ProgramName [ bin | oct | dec | hex ] EXPRESSION"
    echo ""
    echo "NOTES "
    echo "  1 Precision is higher if no (bin/oct/dec/hex) formatting is used. "
    echo "    Also, formatting implies non-fractional output."
    echo ""
    echo "  2 The 'x' character is an alternative for '*' (asterisk) "
    echo "    to do a multiplication. The advantage over using '*' is that "
    echo "    no escaping is required in a shell like 'bash'"
    echo "    - Note that escaping parentheses '(' and ')' will be still "
    echo "      required."
    echo ""
    echo "  3 The Perl interpreter is used to do actual calculation, "
    echo "    available operators are described in 'man perlop'. "
    echo ""
    echo "EXAMPLES"
    echo "    Normal calculation: quoting is used to avoid interpretation "
    echo "    of parentheses by the shell: "
    echo "      \$ calc '(2.4 + 1) x 3'"
    echo "          10.2 = (2.4 + 1) * 3"
    echo ""
    echo "    Add decimal 3 and hexadecimal 0x10 and octal 010 and binary 0b10, "
    echo "    and output result in binary format:"
    echo "      \$ calc bin 3 + 0x10 + 010 + 0b10"
    echo "          0b11101 = 3 + 0x10 + 010 + 0b10"
    echo "    All in decimals this is: "
    echo "      \$ calc dec 3 + 16 + 8 + 2"
    echo "          29 = 3 + 16 + 8 + 2"
    echo ""
    echo "    Note the difference between with or without formatting argument:"
    echo "      \$ calc dec 12345678 x 12.12"
    echo "          149629617 = 12345678 * 12.12"
    echo "      \$ calc  12345678 x 12.12"
    echo "          149629617.36 = 12345678 * 12.12"
    echo ""
    echo "    Simple conversions:"
    echo "      \$ calc hex 65535"
    echo "          0xffff = 65535"
    echo "      \$ calc dec 0xffff"
    echo "          65535 = 0xffff"
    echo ""
    echo "PREREQUISITES"
    echo "    - bash (version 3.1.16(1) used for testing, but any should work)"
    echo "    - perl (version v5.8.8 used for testing, but any >=5 should work)"
    echo ""
    echo "SEE ALSO"
    echo "    man perlop"
    echo ""
    echo "RELATED"
    echo "    - expr, man expr (may help out if 'perl' is not available) "
    echo "    - GUI-based calculators: xcalc, kcalc (just to name a few)"
    echo "    - other command line based calculators "
    echo "    - Gentoo-Linux category sci-calculators"
    echo ""
    echo "VERSION "
    echo "    $ProgramVersionString"
    echo ""
    echo "AUTHOR "
    echo "    Daniel Käps, 2005-2007. "
    echo "    This code is hereby placed in the public domain."
    echo "    There is no warranty, and no liability is assumed."
    echo ""
    exit 1
fi


if [ "$1" == "--version" ] ; then
    echo "$ProgramVersionString"
    exit 0
fi

#--------------------------------------------------------------------------

if [ "$1" == "bin" ] ; then
    FormattingString="0b%b"
elif [ "$1" == "hex" ] ; then
    FormattingString="0x%x"
elif [ "$1" == "oct" ] ; then
    FormattingString="0%o"
elif [ "$1" == "dec" ] ; then
    FormattingString="%d"
else
    FormattingString=""
fi

if [ "$FormattingString" != "" ] ; then
    shift 1
fi

#--------------------------------------------------------------------------

ExpressionString=`echo "$@" | sed 's, x, *,g'`
## echo == "$ExpressionString"

PerlCode=`cat <<.
    \\\$ResultValue = ($ExpressionString);
    if ("$FormattingString" ne "")
      {
        \\\$FormattedResultValue = sprintf("$FormattingString", \\\$ResultValue);
      }
    else
      {
        \\\$FormattedResultValue = \\\$ResultValue;
      }
    # for comparison with unformatted value
    #   print "\\\$ResultValue = \$ExpressionString"; 
    #   print "\n";
    print "\\\$FormattedResultValue = \$ExpressionString"; 
    print "\n";
.
`

#--------------------------------------------------------------------------

## echo ==PerlCode $PerlCode
perl -e "$PerlCode"

#--------------------------------------------------------------------------
