timestr.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  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 Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


partial class TIME_STR < $TEXT, $ANCHORED_FMT

partial class TIME_STR < $TEXT, $ANCHORED_FMT is -- This partial class provides conversions applicable to both time -- of day and elapsed time classes. -- Version 1.0 Oct 98. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 1 Oct 98 kh Original from TIMES class private scan( cursor : STR_CURSOR ) : CARD pre ~void(cursor) and ~cursor.is_done post ((result = CARD::nil) and (initial(cursor.index) = cursor.index)) or (initial(cursor.index) < cursor.index) is -- This routine is the one which does the work of both building and -- of checking the string. If cursor.index is the same on exit as entry -- then the string indicated is not valid. If this is accompanied by -- the return value of CARD::nil then there is a range error, otherwise -- there is a format error. half_day : CARD := 0 ; -- assume twenty-four hour clock start_index : CARD := cursor.index ; loc_lib : LIBCHARS := cursor.buffer.index_lib ; cursor.skip_space ; -- skip padding if ~cursor.item.is_digit then cursor.set_index(start_index) ; return 0 end ; nums : ARRAY{CARD} := ARRAY{CARD}::create(4) ; -- the four possible components field_cnt : CARD := 0 ; decimal_after : CARD := CARD::maxval ; loop loc_str : STR := cursor.get_pred(bind(_.is_digit(loc_lib))) ; nums[field_cnt] := CARD::create(loc_str) ; field_cnt := field_cnt + 1 ; if field_cnt = 4 then break! elsif cursor.is_done then break! else loc_str := cursor.get_pred(bind(_.is_punct(loc_lib))) ; if loc_str.size = 0 then -- premature finish? if cursor.item.is_alpha then -- might be twelve hour suffix loc_str := cursor.get_pred( bind(_.is_alpha(loc_lib))) ; status : TIME_SUFFIX := TIME_SUFFIX::create(str) ; if status.is_nil then -- but it wasn't! cursor.set_index(start_index) ; return 0 else if status = TIME_SUFFIX::Afternoon then half_day := Hours_per_Day / 2 * Millisecs_per_Hr end end ; break! end elsif loc_str[0] = loc_lib.Decimal_Mark.char then decimal_after := field_cnt elsif loc_str.size > 1 then -- can't be a separator cursor.set_index(start_index) ; return 0 end end end ; if (decimal_after < field_cnt) then if (decimal_after /= (field_cnt - 1)) then -- format error! cursor.set_index(start_index) ; return 0 end else if field_cnt = 4 then -- should have had a decimal mark! cursor.set_index(start_index) ; return 0 end end ; case field_cnt when 1 then -- treat value as seconds if nums[0] > Seconds_per_Min then cursor.set_index(start_index) ; return CARD::nil else return nums[0] * Millisecs_per_Sec end when 2 then if decimal_after < field_cnt then -- seconds and millisecs if (nums[0] >= Seconds_per_Min) or (nums[1] >= Millisecs_per_Sec) then cursor.set_index(start_index) ; return CARD::nil else return nums[0] * Millisecs_per_Sec + nums[1] end else -- hours and minutes if ((nums[0] + half_day) >= Hours_per_Day) or (nums[1] >= Minutes_per_Hour) then cursor.set_index(start_index) ; return CARD::nil else return (nums[0] + half_day) * Millisecs_per_Hr + nums[1] * Millisecs_per_Min end end when 3 then if decimal_after < field_cnt then -- minutes, seconds and millisecs if (nums[0] >= Minutes_per_Hour) or (nums[1] >= Seconds_per_Min) or (nums[2] >= Millisecs_per_Sec) then cursor.set_index(start_index) ; return CARD::nil else return nums[0] * Millisecs_per_Min + nums[1] * Millisecs_per_Sec + nums[2] end else -- hours, minutes & seconds if (nums[0] + half_day) >= Hours_per_Day or nums[1] >= Minutes_per_Hour or nums[2] >= Seconds_per_Min then cursor.set_index(start_index) ; return CARD::nil else return (nums[0] + half_day) * Millisecs_per_Hr + nums[1] * Millisecs_per_Min + nums[2] * Millisecs_per_Sec end end when 4 then -- all four if ((nums[0] + half_day) >= Hours_per_Day) or (nums[1] >= Minutes_per_Hour) or (nums[2] >= Seconds_per_Min) or (nums[3] >= Millisecs_per_Sec) then cursor.set_index(start_index) ; return CARD::nil else return (nums[0] + half_day) * Millisecs_per_Hr + nums[1] * Millisecs_per_Min + nums[2] * Millisecs_per_Sec + nums[3] end else return void -- cannot reach here - keep compiler happy! end end ; is_time( str : STR ) : CONVERSION_RESULTS pre true post (result = CONVERSION_RESULTS::All_Right) or (result = CONVERSION_RESULTS::Out_of_Range) or (result = CONVERSION_RESULTS::Bad_Format) or (result = CONVERSION_RESULTS::Empty) is -- This routine checks that the format of of the leading characters of -- the given string in the given repertoire and encoding corresponds to that -- required for a real number, returning the relevant result state. if str.size = 0 then return CONVERSION_RESULTS::Empty end ; start_index : CARD := 0 ; -- just the given string! loc_cursor : STR_CURSOR := str.cursor ; val : CARD := scan(loc_cursor) ; if loc_cursor.index = start_index then -- an error if val = CARD::maxval then return CONVERSION_RESULTS::Out_of_Range else return CONVERSION_RESULTS::Bad_Format end else return CONVERSION_RESULTS::All_Right end end ; build( loc_cursor : STR_CURSOR ) : SAME pre ~void(loc_cursor) and (loc_cursor.remaining > 1) post ((result = val(0)) and (initial(loc_cursor.index) = loc_cursor.index)) or (initial(loc_cursor.index) < loc_cursor.index) is -- This routine creates a time value from the indicated string, returning -- an unchanged cursor if there was some error together with a value of 0 to -- mean a bad format or CARD::nil to indicate some range error. return val(scan(loc_cursor)) end ; create( str : STR ) : SAME pre (is_time(str) = CONVERSION_RESULTS::All_Right) post true is -- This routine creates the whole number corresponding to the textual -- representation contained in str in the given repertoire and encoding. return build(str.cursor) end ; str( lib : LIBCHARS ) : STR pre ~void(lib) post (result.size > 0) is -- This routine returns a string representation of self using the given -- repertoire and encoding. The format will be either fixed point or -- floating point dependent upon the value of self. return lib.culture.date_time.time.fmt(self,lib) end ; str : STR pre true post (result.size > 0) is -- This routine returns a string representation of self using the given -- repertoire and encoding. The format will be either fixed point or -- floating point dependent upon which of the two is the shorter string. return str(LIBCHARS::default) end ; fmt( format : ANCHORED_DESCR, lib : LIBCHARS ) : STR pre ~void(format) and ~void(lib) post result.size > 0 is -- This routine returns a formatted representation of self in the given -- repertoire and encoding as dictated by the given format description. res : STR := str(lib) ; loc_fill : STR := STR::create(lib) + format.filler.char ; if res.size < format.leading then -- needs a filler res := loc_fill.repeat(format.leading - res.size) + res end ; return res end ; fmt( format : ANCHORED_DESCR ) : STR pre ~void(format) post result.size > 0 is -- This routine returns a formatted representation of self in the default -- repertoire and encoding as dictated by the given format description. return fmt(format,LIBCHARS::default) end ; end ; -- TIME_STR