<?php
/* Parse oriented library module.
   Copyright (C) 2007-2009, Future Lab.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, get a copy via the Internet at
   http://gnu.org/copyleft/gpl.html or write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
   MA 02111-1307 USA

   You can contact the author via email at rsmereka@future-lab.com

   Original version. Jul/2007, Rick Smereka */

function tputs($mes)
{
   /* Puts a message using 'echo' prefixed with the time.
      The message is terminated with a carriage return. */

   echo date('H:i:s') . ' ' . $mes . "\n";
}

function isdigit($achar)
{
   /* Evaluate a single character and see if it is a valid base 10
      digit. Only the first character of the string is compared.
      Function returns 'TRUE' if the character is a digit,
      'FALSE' otherwise. */

   if (!isset($achar) || !is_string($achar) || $achar == '')
      return(FALSE);

   $tchar = $achar[0];

   if ($tchar < '0' || $tchar > '9')
      return(FALSE);

   return(TRUE);
}

function num($numstr, $float_allowed = false)
{
   /* Evaluate a string to determine whether it is a valid number.
      Numbers are the digits 0-9. A minus sign is allowed in the
      first character. Function returns 'TRUE' if the string is
      a valid number, 'FALSE' otherwise. */

   if (!isset($numstr) || !is_string($numstr))
      return(FALSE);

   $len = strlen($numstr);

   if (!$len)
      return(FALSE);

   if ($float_allowed)
      {
      $nwords = words($numstr, '.');

      // more than one decimal?
      if ($nwords > 2)
         return false;
 
      // get integer portion
      if (!word($numstr, $wrd, 1, '.'))
         return false;

      // numeric test
      if (!num($wrd))
         return false;

      // does it have a fractional portion?
      if ($nwords > 1)
         {
         // get fractional portion
         if (!word($numstr, $wrd, 2, '.'))
            return false;

         // fractional test
         if (!num($wrd))
            return false;
         }
      }
   else
      {
      for($i = 0; $i < $len; $i++)
         {
         if ($numstr[$i] == '-')
            {
            if ($i > 0)
               return(FALSE);
            }
         else
            if (!isdigit($numstr[$i]))
               return(FALSE);
         }

      return(TRUE);
      }

   return(true);
}

function qatoi($numstr, &$numval)
{
   /* Convert a number in a string to an integer. This function
      differs from 'intval' in the sense that non-numeric characters
      (other than the minus sign) are not allowed. Function returns
      'TRUE' if 'numstr' is a number and 'numval' will be loaded with
      the value. Upon failure, 'FALSE' will be returned and 'numval'
      will be zero. */

   $numval = 0;

   if (!num($numstr))
      return(FALSE);

   $numval = intval($numstr);
   return(TRUE);
}

function alltrim($instr)
{
   /* Trim a string by removing all spaces from the beginning
      and the end plus remove all extra spaces between words.
      Returns the trimmed string. */

   $len = strlen($instr);

   if (!$len)
      return '';

   $tmp = $instr;

   // get position of first non-blank character
   for($i = 0, $pos = -1, $done = false; $i < $len && !$done; $i++)
      if ($tmp[$i] != ' ')
         {
         $pos = $i;
         $done = true;
         }

   // check for all blank string
   if ($pos == -1)
      return '';

   $i = $pos;
   $outstr = '';

   while($i < $len)
      {
      while($tmp[$i] != ' ' && $i < $len)
         {
         $outstr .= $tmp[$i];
         $i++;
         }

      $outstr .= ' ';

      if ($i < $len)
         while($tmp[$i] == ' ' && $i < $len)
            $i++;
      }

   
   return rtrim($outstr);
}

function words($str, $delim = ' ')
{
   // Count the number of 'delim' delimited words in a string.

   $len = strlen($str);

   if (!$len)
      return(0);

   // trim string if delimiter is a space
   $tmp = ($delim == ' ') ? alltrim($str) : $str;
   $len = strlen($tmp);

   // count instances
   for($i = 0, $nwords = 0; $i < $len; $i++)
      if ($tmp[$i] == $delim)
         $nwords++;

   return($nwords + 1);
}

function indxword($instr, $which, $delim = ' ')
{
   /* Return the index of word 'which' within 'instr'
      delimited by 'delim'. Returns the index upon
      success, -1 otherwise. */

   $len = strlen($instr);

   if (!$len)
      return -1;

   // trim string if delimiter is a space
   $tmp = ($delim == ' ') ? alltrim($instr) : $instr;

   if ($which <= 0 || $which > words($tmp, $delim))
      return -1;

   $len = strlen($tmp);

   if (!$len)
      return -1;

   $i = 0;
   $nwords = 1;

   while($i <= $len)
      {
      $index = $i;

      if ($nwords == $which)
         return $index;

      while($tmp[$i] != $delim && $i <= $len)
         $i++;

      $nwords++;
      $i++;
      }

   return -1;
}

function wordlen($instr, $which, $delim = ' ')
{
   /* Get the length of 'delim' delimited word 'which'
      in 'instr'. Returns length upon success,
      -1 otherwise. */

   if (($len = strlen($instr)) == 0)
      return -1;

   // trim string if delimiter is a space
   $tmpstr = ($delim == ' ') ? alltrim($instr) : $instr;
   $len = strlen($tmpstr);
   $nwords = words($tmpstr, $delim);

   if (!$nwords)
      return -1;

   if ($which <= 0 || $which > $nwords)
      return -1;

   if ($which == $nwords)
      $wlen = $len - indxword($tmpstr, $which, $delim);
   else
      $wlen = indxword($tmpstr, $which + 1, $delim) -
              (indxword($tmpstr, $which, $delim) + 1);

   return $wlen;
}

function word($instr, &$outstr, $which, $delim = ' ')
{
   /* Extract the 'which' word of 'instr' and return it in 'outstr'.
      Each word is delimited by 'delim'. Returns 'true' upon
      success, 'false' otherwise. */

   $len = strlen($instr);
   $outstr = '';

   if (!$len)
      return false;

   if ($which <= 0 || $which > words($instr, $delim))
      return false;

   $pos = indxword($instr, $which, $delim);
   $len = wordlen($instr, $which, $delim);
   $outstr = substr($instr, $pos, $len);
   return true;
}

function lpad($istr, $padch, $len)
{
   /* Pad the string 'istr' on the left with the 'padch'
      to the desired 'len'gth.
      Returns the new string. */

   $padstr = "";
   $length = strlen($istr);

   // if string is already long enough, exit
   if ($length >= $len)
      return $istr;

   for($i = $length; $i < $len; $i++)
      $padstr .= $padch;

   return $padstr . $istr;
}

function rpad($istr, $padch, $len)
{
   /* Pad the string 'istr' on the right with the 'padch'
      to the desired 'len'gth.
      Returns the new string. */

   $padstr = "";
   $length = strlen($istr);

   // if string is already long enough, exit
   if ($length >= $len)
      return $istr;

   for($i = $length; $i < $len; $i++)
      $padstr .= $padch;

   return $istr . $padstr;
}

function delbytes($instr, &$outstr, $pos, $numbytes = 0)
{
   /* Delete the 'numbytes' of 'instr' starting from byte 'pos'
      and place the result string into 'outstr'. Returns 'true'
      upon success with the result string in 'outstr', 'false'
      otherwise. 'numbytes' may be zero which indicates the
      remainder of the string. */
   $outstr = '';
   $instrlen = strlen($instr);

   if ($instr == '' || $pos < 0 || $numbytes < 0 || ($pos + $numbytes) > $instrlen)
      return false;

   $beg = '';
   $end = '';

   // loop to copy all data before the start position 'pos'
   for($i = 0; $i < $pos; $i++)
      $beg .= $instr[$i];

   // calc the number of bytes to delete
   $slen = ($numbytes) ? $numbytes : $instrlen - $pos;

   // loop to copy all data after the removed section
   for($i = $pos + $slen, $j = 0; $i < $instrlen; $i++, $j++)
      $end .= $instr[$i];

   $outstr = $beg . $end;
   return true;
}

function worddel($instr, &$outstr, $which, $delim = ' ')
{
   /* Delete the 'which' word of 'instr' delimited by 'delim'.
      Upon success, 'outstr' will be loaded with the new string.
      Returns 'true' upon success, 'false' otherwise. */
   if (!strlen($instr) || $which <= 0)
      return false;

   $outstr = '';
   $nwords = words($instr, $delim);

   if ($which > $nwords)
      return false;

   $pos = indxword($instr, $which, $delim);

   if ($nwords == $which)
      {
      // 'delbytes' uses zero len to indicate the rest of the string
      $num_bytes = 0;

      /* if there is more than one word and we are deleting the last,
         back up one byte to remove the delimiter */

      if ($nwords > 1)
         $pos--;
      }
   else
      $num_bytes = indxword($instr, $which + 1, $delim) - $pos;

   if (!delbytes($instr, $result, $pos, $num_bytes))
      return false;

   $outstr = $result;
   return true;
}
?>
