#!/bin/bash
# Skrypt validfloat sprawdza, czy podana wartość reprezentuje liczbę zmiennoprzecinkową.
# Pamiętaj, że liczba nie może być zapisana w formacie naukowym (np. 1.304e5).

# Aby sprawdzić, czy podana wartość reprezentuje liczbę zmiennoprzecinkową,
# trzeba podzielić ją na dwie części: całkowitą i ułamkową. Następnie trzeba 
# sprawdzić, czy pierwsza część reprezentuje liczbę całkowitą, a druga –
# liczbę całkowitą nieujemną. W ten sposób wartość -30,5 będzie oceniona
# jako poprawna, a -30,-8 jako błędna liczba.

# Aby w jednym skrypcie wykorzystać inny, należy poprzedzić jego nazwę
# kropką (.). To proste.

. validint   # Sposób wywoływania skryptu validint w powłoce bash.

validfloat()
{
  fvalue="$1"

  # Sprawdzenie, czy podana wartość zawiera przecinek.
  if [ ! -z $(echo $fvalue | sed 's/[^, ]//g') ] ; then

    # Wyodrębnienie części wartości po lewej stronie przecinka
    # (np. '3' z liczby '3,14').
    decimalPart="$(echo $fvalue | cut -d, -f1)"

    # Wyodrębnienie części wartości po prawej stronie przecinka
    # (np. '14' z '3,14').
    fractionalPart="${fvalue#*\,}"

    # Sprawdzenie najpierw części dziesiętnej, czyli znajdującej się
    # po lewej stronie przecinka.

    if [ ! -z $decimalPart ] ; then
      # Znak "!" oznacza negację wyniku wyrażenia, więc poniższy zapis oznacza
      # "jeżeli wyrażenie NIE jest liczbą całkowitą".
      if ! validint "$decimalPart" "" "" ; then
        return 1
      fi 
    fi

    # Sprawdzenie części ułamkowej (po prawej stronie przecinka).
    # Przede wszystkim na początku nie może być znaku odejmowania,
    # jak np. w wartości 33,-11, więc w trzeba sprawdzić, czy
    # w tej części jest znak '-'.
    if [ "${fractionalPart%${fractionalPart#?}}" = "-" ] ; then
      echo "Błędna liczba zmiennoprzecinkowa: po przecinku nie może" \
        "być znaku '-'." >&2         # Zapis >&2 powoduje wysłanie tekstu do kanału stderr.
      return 1
    fi 
    if [ "$fractionalPart" != "" ] ; then 
      # Jeżeli część ułamkowa NIE jest poprawną liczbą całkowitą...
      if ! validint "$fractionalPart" "0" "" ; then
        return 1
      fi
    fi
  else 
    # Jeżeli cała wartość składa się tylko ze znaku "-", to też nie jest dobrze.
    if [ "$fvalue" = "-" ] ; then
      echo "Błędny format liczby zmiennoprzecinkowej." >&2 ; return 1
    fi

    # Na koniec sprawdzamy, czy pozostałe cyfry reprezentują
    # poprawną liczbę całkowitą.
    if ! validint "$fvalue" "" "" ; then
      return 1
    fi
  fi

  return 0
}

# POCZĄTEK GŁÓWNEJ CZĘŚCI. USUŃ LUB ZAMIEŃ W KOMENTARZ KOD PONIŻEJ TEGO WIERSZA,
# JEŻELI TEN SKRYPT BĘDZIE WYKORZYSTYWANY W INNYCH SKRYPTACH.
# =================

#if validfloat $1 ; then
#  echo "$1 jest poprawną liczbą zmiennoprzecinkową."
#fi

#exit 0
