EiffelBase class
(HTML page generated by ISE Eiffel 4.2)
Eiffel Class
indexing
description: "Formatter for integral numbers";
status: "See notice at end of class";
names: format_integer;
date: "$Date: 2007-03-30 11:10:11 -0800 (Fri, 30 Mar 2007) $";
revision: "$Revision: 95354 $"
class FORMAT_INTEGER
creation
make
feature -- Initialization
make (w: INTEGER) is
require
reasonable_field: w >= 1
do
blank_fill;
width := w;
sign_normal;
sign_negative_only;
right_justify
ensure
blank_fill: fill_character = ' ';
show_sign_negative: show_sign_negative;
no_separator: no_separator;
width_set: width = w;
right_justified: right_justified;
leading_sign: leading_sign
end;
feature -- Access
fill_character: CHARACTER;
-- Padding character.
width: INTEGER;
-- Width of the field.
separator: CHARACTER;
-- Separator between 1000's of numbers.
justification: INTEGER;
-- Where in the field the format goes.
trailing_sign: BOOLEAN;
-- Is the sign at the end?
sign_format: INTEGER;
-- How the sign is formatted.
sign_string: STRING;
-- Formatting details for the sign.
bracketted_negative: BOOLEAN;
-- Enclose negative numbers in brackets?
feature -- Status report
centered: BOOLEAN is
-- Are numbers to be formatted centered?
do
Result := justification = center_justification
ensure
Result = (justification = center_justification)
end;
left_justified: BOOLEAN is
-- Are numbers to be formatted with spaces on the right?
do
Result := justification = left_justification
ensure
Result = (justification = left_justification)
end;
right_justified: BOOLEAN is
-- Are numbers to be formatted with spaces on the left?
do
Result := justification = right_justification
ensure
Result = (justification = right_justification)
end;
not_justified: BOOLEAN is
-- Are numbers to be formatted in smallest string possible
do
Result := justification = no_justification
ensure
Result = (justification = no_justification)
end;
show_sign_negative: BOOLEAN is
-- Are numbers to show sign only when negative?
do
Result := sign_format = sign_negative_value
ensure
Result = (sign_format = sign_negative_value)
end;
show_sign_positive: BOOLEAN is
-- Are numbers to show sign only when positive?
do
Result := sign_format = sign_positive_value
ensure
Result = (sign_format = sign_positive_value)
end;
show_sign: BOOLEAN is
-- Are numbers to show sign whether positive or negative?
do
Result := sign_format = show_sign_value
ensure
Result = (sign_format = show_sign_value)
end;
ignore_sign: BOOLEAN is
-- Ignore the sign of a number?
do
Result := sign_format = ignore_sign_value
ensure
Result = (sign_format = ignore_sign_value)
end;
no_separator: BOOLEAN is
-- Is there a separator?
do
Result := separator = '%U'
ensure
Result = (separator = '%U')
end;
leading_sign: BOOLEAN is
-- Is the sign leading?
do
Result := nottrailing_sign
ensure
Result = nottrailing_sign
end;
feature -- Status setting
blank_fill is
-- Fill numbers with blanks.
do
fill_character := ' '
ensure
fill_character = ' '
end;
zero_fill is
-- Fill numbers with zeros.
do
fill_character := '0'
ensure
fill_character = '0'
end;
dollar_fill is
-- Fill numbers with dollars.
do
fill_character := '$'
ensure
fill_character = '$'
end;
asterisk_fill is
-- Fill numbers with asterisks.
do
fill_character := '*'
ensure
fill_character = '*'
end;
set_fill (c: CHARACTER) is
-- Fill numbers with c
do
fill_character := c
ensure
fill_character = c
end;
set_width (w: INTEGER) is
-- Set width to w
require
wide_enough: w >= 1
do
width := w
ensure
width = w
end;
underscore_separate is
-- Set separator to underscore.
do
separator := '_'
ensure
separator = '_'
end;
comma_separate is
-- Set separator to comma.
do
separator := ','
ensure
separator = ','
end;
dot_separate is
-- Set separator to period.
do
separator := '.'
ensure
separator = '.'
end;
remove_separator is
-- Remove the separator.
do
separator := '%U'
ensure
separator = '%U'
end;
set_separator (c: CHARACTER) is
-- Set the separator to c
do
separator := c
ensure
separator = c
end;
left_justify is
--Put padding on right
do
justification := left_justification
ensure
left_justified
end;
center_justify is
-- Put padding on right and left
do
justification := center_justification
ensure
centered
end;
right_justify is
-- Put padding on left
do
justification := right_justification
ensure
right_justified
end;
no_justify is
-- Always return the smallest string possible
do
justification := no_justification
ensure
not_justified
end;
sign_leading is
-- Set the sign to lead
do
trailing_sign := false
ensure
leading_sign
end;
sign_trailing is
-- Set the sign to trail
do
trailing_sign := true
ensure
trailing_sign
end;
sign_positive_only is
-- Show sign for positive numbers only.
do
sign_format := sign_positive_value
ensure
show_sign_positive
end;
sign_negative_only is
-- Show sign for negative numbers only.
do
sign_format := sign_negative_value
ensure
show_sign_negative
end;
sign_show is
-- Show sign for all numbers.
do
sign_format := show_sign_value
ensure
show_sign
end;
sign_ignore is
-- Do not show sign.
do
sign_format := ignore_sign_value
ensure
ignore_sign
end;
sign_normal is
-- Set sign for - and +.
do
sign_string := "- +"
ensure
sign_string.is_equal ("- +")
end;
sign_cr_dr is
-- Set sign for CR/DR
do
sign_string := "CR DR"
ensure
sign_string.is_equal ("CR DR")
end;
sign_dr_cr is
-- Set sign for DR/CR
do
sign_string := "DR CR"
ensure
sign_string.is_equal ("DR CR")
end;
sign_floating_dollar is
-- Set sign for floating dollar.
do
sign_string := "$$$";
sign_leading
ensure
sign_string.is_equal ("$$$")
end;
sign_floating_dollar_signed is
-- Set sign for floating dollar include sign.
do
sign_string := "-$ $+$";
sign_leading
ensure
sign_string.is_equal ("-$ $+$")
end;
set_sign (s: STRING) is
-- Set sign values for positive, zero, negative
-- All values must be the same length.
-- Stored as negative, zero, positive.
require
s /= void;
s.count >= 3;
s.count \\ 3 = 0
do
sign_string := clone (s)
ensure
sign_string.is_equal (s)
end;
bracket_negative is
-- Bracket negative numbers.
do
bracketted_negative := true
ensure
bracketted_negative
end;
unbracket_negative is
-- Do not bracket negative numbers.
do
bracketted_negative := false
ensure
notbracketted_negative
end;
feature -- Conversion
formatted (i: INTEGER): STRING is
-- Format the integer.
local
sign: INTEGER;
unsigned: INTEGER
do
if i < 0 then
sign := -1;
unsigned := -i
elseif i > 0 then
sign := 1;
unsigned := i
end;
if notno_separator then
Result := split (unsigned.out)
else
Result := clone (unsigned.out)
end;
if notignore_sign or bracketted_negative then
Result := process_sign (Result, sign)
end;
if justification /= no_justification and then Result.count < width then
Result := justify (Result)
end
ensure
exists: Result /= void;
correct_length: not_justified or Result.count >= width
end;
feature {NONE} -- Implementation
No_justification: INTEGER is 0;
Left_justification: INTEGER is 1;
Center_justification: INTEGER is 2;
Right_justification: INTEGER is 3;
Show_sign_value: INTEGER is 0;
Ignore_sign_value: INTEGER is 1;
Sign_positive_value: INTEGER is 2;
Sign_negative_value: INTEGER is 3;
split (s: STRING): STRING is
-- Apply separators to an integer
require
efficiency: separator /= '%U'
local
count, sep_length: INTEGER
do
from
count := s.count;
create Result.make (width)
until
count <= 3
loop
from
sep_length := 0
until
sep_length = 3
loop
Result.precede (s.item (count));
count := count - 1;
sep_length := sep_length + 1
end;
Result.precede (separator)
end;
from
until
count = 0
loop
Result.precede (s.item (count));
count := count - 1
end
end;
process_sign (s: STRING; sn: INTEGER): STRING is
-- Process sign related values.
local
sstring: STRING
do
Result := s;
if bracketted_negative and sn = -1 then
Result.precede ('(');
Result.extend (')')
end;
if ((show_sign_negative or show_sign) and sn = -1) or else ((show_sign_positive or show_sign) and sn = 1) or else (show_sign and sn = 0) then
sstring := sign_value (sn)
end;
if sstring /= void then
if trailing_sign then
Result.append (sstring)
else
Result.prepend (sstring)
end
end
end;
sign_size: INTEGER is
-- Size of the sign.
do
Result := sign_string.count // 3
ensure
Result * 3 = sign_string.count
end;
sign_value (i: INTEGER): STRING is
-- Value of the sign.
require
correct_sign: -1 <= i and i <= 1
local
t: INTEGER
do
t := sign_size * (i + 1) + 1;
Result := sign_string.substring (t, t + sign_size - 1)
end;
justify (s: STRING): STRING is
-- Justify s.
require
room: s.count < width;
justification: justification /= no_justification
local
l, r: STRING;
i, t: INTEGER
do
Result := s;
if notcentered then
create l.make (width - s.count);
from
i := 1
until
i > l.capacity
loop
l.extend (fill_character);
i := i + 1
end;
if left_justified then
Result.append (l)
else
Result.prepend (l)
end
else
t := (width - s.count) // 2;
if 2 * t + s.count < width then
create l.make (t + 1)
else
create l.make (t)
end;
create r.make (t);
from
i := 1
until
i > r.capacity
loop
l.extend (fill_character);
r.extend (fill_character);
i := i + 1
end;
if i = l.capacity then
l.extend (fill_character)
end;
Result.prepend (l);
Result.append (r)
end
end;
invariant
sign_string_constraint: sign_string /= void;
wide_enough: width >= 1;
no_justification <= justification and justification <= right_justification;
end -- class FORMAT_INTEGER
|