wholestr.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 WHOLE_STR{T} < $TEXT, $EXACT_FMT
partial class WHOLE_STR{T} < $TEXT, $EXACT_FMT is
-- This partial class provides numeric whole number conversion routines,
-- to and from character strings and a numeric integral immutable 'value'.
-- Version 1.2 Jun 2001. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 15 Sep 98 kh Original from Modula-2 standard
-- 2 Oct 98 kh use Sather mechanisms rather than M-2 ones
-- 1 Jun 01 kh removed raw_str (zero-filled provides same)
private const Octal_Base : CARD := 8 ;
private const Decimal_Base : CARD := 10 ;
private const Hexadecimal_Base : CARD := 16 ;
private const Default_Base : CARD := Decimal_Base ;
private scan(
cursor : STR_CURSOR,
base : CARD
) : SAME
pre ~void(cursor)
and ~cursor.is_done
post ((result = T::nil)
and (initial(cursor.index) = cursor.index))
or (initial(cursor.index) < cursor.index)
is
-- This routine is the integer number scanner which, if successful,
-- returns the value of the number found (using the given base). If on exit
-- the cursor is unchanged then the return value of zero indicates that no
-- number was found, while returning nil means that the number found
-- is out of bounds.
start_index : CARD := cursor.index ;
loc_lib : LIBCHARS := cursor.buffer.index_lib ;
loc_format : NUMBER_FMT := loc_lib.culture.numeric.format ;
res : SAME := zero ;
digits : FLIST{CARD} := loc_format.digit_string(cursor,true,base) ;
if void(digits) then
cursor.set_index(start_index) ;
return nil
end ;
loop
loc_digit : CARD := digits.elt! ;
if (maxval - res).card < loc_digit then
cursor.set_index(start_index) ;
return nil
else
res := create(res.card * base + loc_digit)
end
end ;
return res
end ;
private is_kind(
cursor : STR_CURSOR,
base : CARD
) : CONVERSION_RESULTS
pre ~void(cursor)
and ~cursor.is_done
and ((base = Octal_Base)
or (base = Decimal_Base)
or (base = Hexadecimal_Base))
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 the leading characters of
-- the given string in the given repertoire and encoding corresponds to that
-- required for a cardinal number in the given base.
if cursor.remaining = 0 then
return CONVERSION_RESULTS::Empty
end ;
start_index : CARD := cursor.index ;
val : T := scan(cursor,base) ;
if start_index = cursor.index then -- bad or too large
if val = 0 then
return CONVERSION_RESULTS::Bad_Format
else
return CONVERSION_RESULTS::Out_of_Range
end
else
cursor.set_index(start_index) ;
return CONVERSION_RESULTS::All_Right
end
end ;
is_whole(
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 using the given repertoire and encoding corresponds to
-- that required for a cardinal number to the base 10.
if str.size = 0 then
return CONVERSION_RESULTS::Empty
else
return is_kind(str.cursor,Decimal_Base)
end
end ;
is_octal(
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 using the given repertoire and encoding corresponds to
-- that required for a cardinal number to the base 8.
if str.size = 0 then
return CONVERSION_RESULTS::Empty
else
return is_kind(str.cursor,Octal_Base)
end
end ;
is_hex(
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 using the given repertoire and encoding corresponds to
-- that required for a cardinal number to the base 16.
if str.size = 0 then
return CONVERSION_RESULTS::Empty
else
return is_kind(str.cursor,Hexadecimal_Base)
end
end ;
build_based(
loc_cursor : STR_CURSOR,
base : CARD
) : SAME
pre ~void(loc_cursor)
and ((base = Octal_Base)
or (base = Decimal_Base)
or (base = Hexadecimal_Base))
post (initial(loc_cursor.index) = loc_cursor.index)
or (initial(loc_cursor.index) < loc_cursor.index)
is
-- This routine creates the whole number corresponding to the textual
-- representation contained in the string indicated. If the string indicated
-- does not contain an exact number as the next non-blank item in the string
-- then zero is returned and the cursor has not been moved! If the number is
-- out of range then CARD::nil is returned with an unchanged cursor.
--
-- NOTE NO format prefix should precede the number digits (eg it is not
-- valid to pass a cursor indicating a string "0x1234" and expect
-- that the routine will return the value 4660! It will return zero
-- and the next item in the string will be the letter 'x'!
return scan(loc_cursor,base)
end ;
build(
loc_cursor : STR_CURSOR
) : SAME
pre ~void(loc_cursor)
and ~loc_cursor.is_done
post (initial(loc_cursor.index) = loc_cursor.index)
or (initial(loc_cursor.index) < loc_cursor.index)
is
-- This routine creates the whole number corresponding to the textual
-- representation contained in str.
return build_based(loc_cursor,Default_Base)
end ;
create(
str : STR
) : SAME
pre (is_whole(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_based(str.cursor,Default_Base)
end ;
oct_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.
return lib.culture.numeric.format.fmt(self.card,Octal_Base,lib).tgt_str
end ;
oct_str : STR
pre true
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding.
return oct_str(LIBCHARS::default)
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.numeric.format.fmt(card,Default_Base,lib).tgt_str
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 ;
private zero_filled(
lib : LIBCHARS,
width : CARD,
base : CARD
) : CODE_STR
pre ~void(lib)
and width > 0
and base <= Hexadecimal_Base
post (result.size > 0)
is
-- This routine returns a code string representation of self using the
-- given repertoire and encoding. It relies upon the fact that binary, octal
-- and decimal digits are a sub-set of hexadecimal digits. Note that the
-- international standard numeric formatting is NOT used for this character
-- form. The code string is produced Least Significant digit first
-- (ie 'reversed').
res : CODE_STR := CODE_STR::create(lib) ;
starting : BOOL := true ; -- ensures at least one char!
val : CARD := self.card ;
loop
cnt : CARD := 0.up! ;
if starting
or val > 0 then
starting := false ;
digit_num : CARD := val % base ;
res := res + lib.hex_digit(digit_num) ;
val := val / base
elsif cnt < width then -- leading zeroes!
res := res + lib.hex_digit(0)
else
break!
end
end ;
return res
end ;
decimal_str(
lib : LIBCHARS,
char_cnt : CARD
) : STR
pre ~void(lib)
and char_cnt > 0
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting is NOT used for this character form.
return zero_filled(lib,char_cnt,Decimal_Base).tgt_str.reverse
end ;
hex_str(
lib : LIBCHARS,
char_cnt : CARD
) : STR
pre ~void(lib)
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting is NOT used for this character form.
return zero_filled(lib,char_cnt,Hexadecimal_Base).tgt_str.reverse
end ;
decimal_str(
lib : LIBCHARS
) : STR
pre ~void(lib)
post (result.size > 0)
is
-- This routine returns a decimal string representation of self using
-- the given repertoire and encoding. Note that the international standard
-- numeric formatting is NOT used for this character form.
return zero_filled(lib,1,Decimal_Base).tgt_str.reverse
end ;
hex_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. Note that the international standard numeric
-- formatting is NOT used for this character form.
return zero_filled(lib,NUM_BITS::Octets_per_Card * 2,
Hexadecimal_Base).tgt_str.reverse
end ;
decimal_str(
char_cnt : CARD
) : STR
pre (char_cnt > 0)
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting representation is NOT used for this character form.
return zero_filled(LIBCHARS::default,char_cnt,
Decimal_Base).tgt_str.reverse
end ;
hex_str(
char_cnt : CARD
) : STR
pre (char_cnt > 0)
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting representation is NOT used for this character form.
return zero_filled(LIBCHARS::default,char_cnt,
Hexadecimal_Base).tgt_str.reverse
end ;
decimal_str : STR
pre true
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting is NOT used for this character form.
return zero_filled(LIBCHARS::default,1,Decimal_Base).tgt_str.reverse
end ;
hex_str : STR
pre true
post (result.size > 0)
is
-- This routine returns a string representation of self using the given
-- repertoire and encoding. Note that the international standard numeric
-- formatting is NOT used for this character form.
return zero_filled(LIBCHARS::default,NUM_BITS::Octets_per_Card * 2,
Hexadecimal_Base).tgt_str.reverse
end ;
fmt(
format : EXACT_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) ;
if res.size < format.whole_digits then -- needs a filler
res := STR::create(format.filler.card,lib).repeat(
format.whole_digits - res.size) + res
end ;
return res
end ;
fmt(
format : EXACT_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,format.filler.lib)
end ;
end ; -- WHOLE_STR