culture.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> <--------------
class CULTURE < $IS_EQ
class CULTURE < $IS_EQ is
-- This class embodies a binary version of the 'locale' files defined
-- in ISO/IEC 14652, finding and reading the appropriate one as needed.
--
-- There are twelve different kinds of service specified at present.
-- They are given the names following - to provide for backwards compatibility
-- with the Posix standard (ISO/IEC 9945-2).
--
-- LC_CTYPE -- Built-in to code classes!
-- LC_COLLATE
-- LC_NUMERIC
-- LC_MONETARY
-- LC_TIME
-- LC_MESSAGES
-- LC_PAPER
-- LC_NAME
-- LC_ADDRESS
-- LC_TELEPHONE
-- LC_MEASUREMENT
-- LC_VERSION
-- The auxiliary programs provided with this library provide for the
-- construction of a binary version of the string-form definitions. This
-- is need because it is not possible to know that anything is text until
-- the binary files have been read to establish the coding scheme in use and
-- enable characters, etc to be handled correctly.
-- The two binary files are the culture file and the separate collate
-- file. The former is read when initialising this class and used to
-- establish values for all categories except collation. The collate file
-- is read and used by the class REPERTOIRE as needed, being 'created' during
-- the initialisation of this class.
-- NOTE The arrays of string for day of week, etc are located by
-- the appropriate enumeration when needed.
-- Version 1.2 Jun 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 9 Dec 96 kh Original
-- 19 Feb 97 kh Additions for string/char portability.
-- 26 Jun 98 kh Restructured for revised standard!
-- The first two constants specify in a portable manner the names
-- of the two environment variables on which this library depends -
-- SATHER_HOME
-- LOCALE
include COMPARABLE ;
const -- list of valid creation states
Start, Library, Culture, Charmap, Collating, All ;
private shared priv_default : SAME ; -- to ensure there is only one!
readonly attr state : CARD ;
readonly attr resource_path : FILE_PATH ;
-- This string contains the culture-specific path name segment for
-- use when the RESOURCES class is creating class message file names.
private attr priv_kind : CODE_KINDS ;
private attr priv_collating : REPERTOIRE ;
private attr priv_charmap : REP_MAP ;
private attr priv_resources : RESOURCES ;
private attr priv_sather_lib : LIBCHARS ;
-- The five objects above are various components of this culture (see
-- the class definitions).
-- The following individual components each contain the sub-components
-- of locale specification as outlined in ISO/IEC 14652 and the Sather
-- cultural compiler.
readonly attr char_data : CHAR_TYPES ;
-- LC_NUMERIC format
readonly attr numeric : NUMBERS ;
-- LC_MONETARY formats, etc
readonly attr currency : CASH ;
-- LC_TIME formats
readonly attr date_time : TEMPORAL ;
-- LC_MESSAGES components.
private attr priv_answers : ANSWERS ;
-- LC_PAPER components.
readonly attr paper_size : RECTANGLE ;
-- LC_NAME components.
readonly attr naming : NAMING ;
-- LC_ADDRESS components.
readonly attr addressing : ADDRESSING ;
-- LC_TELEPHONE component
readonly attr phoning : PHONING ;
-- LC_MEASUREMENT component
readonly attr units : UNIT_KINDS ;
-- LC_VERSION component
readonly attr version : VERSION ;
Home_ref : STR is
-- This routine gives global access to the name of the SATHER_HOME
-- environment variable in the local default culture as a reference string.
loc_lib : LIBCHARS := priv_sather_lib ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_S.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_A.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_T.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_H.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_E.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_R.card,loc_lib) +
CHAR_CODE::create(UNICODE::LOW_LINE.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_H.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_O.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_M.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_E.card,loc_lib) ;
res : STR := loc_res.tgt_str ;
return res
end ;
-- NOTE The following routines - Locale_ref, Res_ref,
-- Default_ref and Leaf_name_ref are only for use in this
-- class when creating the default culture!!
private Locale_ref : STR is
-- This routine creates and returns the name of LOCALE as a
-- reference string.
loc_lib : LIBCHARS := priv_sather_lib ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_L.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_O.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_C.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_A.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_L.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_CAPITAL_LETTER_E.card,loc_lib) ;
return loc_res.tgt_str
end ;
private Res_ref : STR is
-- This routine creates and returns the name of the resources
-- sub-directory in the SATHER_HOME directory as a reference string.
loc_lib : LIBCHARS := priv_sather_lib ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_R.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_E.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_S.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_O.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_U.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_R.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_C.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_E.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_S.card,loc_lib) ;
res : STR := loc_res.tgt_str ;
return res
end ;
private Default_ref : STR is
-- This routine creates and returns the name of the default sub-directory
-- in the Resources sub-directory as a reference string.
loc_lib : LIBCHARS := priv_sather_lib ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_D.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_E.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_F.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_A.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_U.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_L.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_T.card,loc_lib) ;
return loc_res.tgt_str
end ;
-- The leaf name for the primary culture file is 'culture', eg the
-- default file is
--
-- $SATHER_HOME/Resources/default/bin/culture on a unix system
private Leaf_Name_ref : STR is
-- This routine creates and returns the name of the default sub-directory
-- in the Resources sub-directory as a reference string. Note that this always
-- uses the default library in order to communicate with the operating system!
loc_lib : LIBCHARS := priv_sather_lib ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_C.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_U.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_L.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_T.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_U.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_R.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_E.card,loc_lib) ;
return loc_res.tgt_str
end ;
private Bin_ref : STR is
-- This fourth 'constant' routine creates and returns the name of the
-- default sub-directory in the Resources sub-directory as a reference string.
-- Note that this routine is also invoked by the next following routine
-- bin_resource_path - which is used both when creating a default cuoture
-- and for all other cultures. Therefore the library used must always be
-- the default 'local' one.
loc_lib : LIBCHARS := LIBCHARS::default ;
loc_res : CODE_STR := CODE_STR::create(loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_B.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_I.card,loc_lib) +
CHAR_CODE::create(UNICODE::LATIN_SMALL_LETTER_N.card,loc_lib) ;
return loc_res.tgt_str
end ;
bin_resource_path : FILE_PATH is
-- The directory for the binary culture files
return resource_path.append(Bin_ref)
end ;
private parse_locale(
str_index : BIN_CURSOR
) : BOOL
pre ~void(str_index)
and ~str_index.is_done
and ~void(self)
post true -- the object is completed!
is
-- This is the routine which reads the locale culture file into
-- the internal components. The order of components is that frequently
-- found in the source locale files -- but that is purely coincidence!
if (priv_kind /= CODE_KINDS::create(str_index.get_item.card)) then
SYS_ERROR::blind_error(self,resource_path.str,priv_sather_lib)
end ;
char_data := CHAR_TYPES::build(str_index) ;
currency := CASH::build(str_index,priv_sather_lib) ;
date_time := TEMPORAL::build(str_index,priv_sather_lib) ;
-- NOTE The TEMPORAL class does NOT include the alternate digits
-- which may be specified as part of the date/time group in
-- the ISO/IEC standard and which are, if present, part of
-- the NUMBERS class in this library. It is important,
-- therefore that the date/time class is read IMMEDIATELY
-- before the numbers data!!
numeric := NUMBERS::build(str_index,priv_sather_lib) ;
priv_answers := ANSWERS::build(str_index,priv_sather_lib) ;
-- NOTE The following components are 'read' which permits them
-- to be void after a Boolean.
paper_size := RECTANGLE::read(str_index) ;
naming := NAMING::read(str_index,priv_sather_lib) ;
addressing := ADDRESSING::read(str_index,priv_sather_lib) ;
phoning := PHONING::read(str_index,priv_sather_lib) ;
units := UNIT_KINDS::read(str_index) ;
version := VERSION::read(str_index,priv_sather_lib) ;
return str_index.is_done
end ;
private default_path : FILE_PATH
pre true
post ~void(result)
is
-- This routine is used by all non-locale classes to determine the name
-- of the file which must be read in order to create the respective object.
sather_home : STR := OPSYS::get_env(Home_ref) ;
-- NOTE the above 'string' may not be in human readable form!
if void(sather_home) then -- Fatal error!
SYS_ERROR::blind_error(self,Home_ref,priv_sather_lib)
end ;
home : FILE_PATH := FILE_PATH::create(sather_home).append(Res_ref) ;
locale : STR := OPSYS::get_env(Locale_ref) ;
-- NOTE the above string may not be in human readable form!
if void(locale) then -- need to use 'Default'
locale := Default_ref
end ;
res : FILE_PATH := home.append(locale).append(
Bin_ref).append(Leaf_Name_ref) ;
return res
end ;
private create_from_files(
me : SAME,
file_path : FILE_PATH
) : SAME
pre ~void(me)
post ~void(result.priv_charmap)
and ~void(result.priv_collating)
and ~void(result.priv_resources)
and ~void(result.priv_sather_lib)
is
-- This routine is the one which does the actual creation of all the
-- components from the data files indicated by the path given.
-- The first step is to obtain access to the Sather-specific
-- environment descriptor which establishes the local Sather
-- 'culture' and various file path and mode tokens.
if void(file_path) then -- This is the default culture!
priv_default := me
end ;
me.priv_sather_lib := LIBCHARS::create(me,file_path) ;
if void(me.priv_sather_lib) then -- Cannot proceed further!!
SYS_ERROR::blind_error(me,file_path.str,void)
end ;
me.state := Library ;
loc_path : FILE_PATH ;
if void(file_path) then -- This is the default culture!
loc_path := me.default_path
else
loc_path := file_path
end ;
me.resource_path := loc_path.head.head ;
culture_file : BIN_FILE := BIN_FILE::open_for_read(loc_path.str) ;
if void(culture_file) -- name OK, but couldn't find it!!
or culture_file.error then
SYS_ERROR::blind_error(me,loc_path.str,me.priv_sather_lib)
end ;
loc_buff : FBINSTR := culture_file.buffer ;
file_cursor : BIN_CURSOR := loc_buff.binstr.cursor ;
culture_file.close ;
if ~me.parse_locale(file_cursor) then
SYS_ERROR::blind_error(me,loc_path.str,me.priv_sather_lib)
end ;
me.state := Culture ;
-- WARNING: The following three assignments, which all use
-- components already created, MUST be done in
-- the order charmap, collating, resources!
-- THEIR SUCCESSFUL CREATION DEPENDS ON THIS!!!!!!!
me.priv_charmap := REP_MAP::create(me) ;
if void(me.priv_charmap) then
SYS_ERROR::blind_error(me,loc_path.str,me.priv_sather_lib)
end ;
me.state := Charmap ;
me.priv_collating := REPERTOIRE::create(me) ;
if void(me.priv_collating) then
SYS_ERROR::blind_error(me,
file_path.head.append(REPERTOIRE::Leaf_Name_ref).str,
me.priv_sather_lib)
end ;
me.state := Collating ;
me.priv_resources := RESOURCES::create(me) ;
if void(me.priv_resources)
and (me /= priv_default) then
SYS_ERROR::blind_error(me,
file_path.head.append(RESOURCES::Leaf_Name_ref).str,
me.priv_sather_lib)
end ;
me.state := All ;
return me
end ;
create(
file_path : FILE_PATH
) : SAME
pre true
post ~void(result) -- or an exception raised!
is
-- This creation routine sets up the appropriate file path from
-- the given file_name and then creates the culture object from the files
-- so found.
me : SAME := new ;
me.state := Start ;
return create_from_files(me,file_path)
end ;
private initialise : SAME
pre true
post ~void(result)
is
-- This routine returns the default culture by obtaining the file name
-- from the current program environment and invoking the create routine.
void_path : FILE_PATH := void ;
return create(void_path)
end ;
private init : SAME
pre true
post ~void(result)
is
-- This routine is used everywhere that a need for the shared values of
-- this class are required -- to check if the values have been initialised,
-- reading from files if not.
if void(priv_default) then
return initialise
else
return priv_default
end
end ;
default : SAME
pre true
post ~void(result)
is
-- This routine returns the default culture by obtaining the file name
-- from the current program environment and invoking the init routine which
-- follows.
return init
end ;
is_eq(
other : SAME
) : BOOL is
-- This predicate returns true if and only if self and other are the same
-- object, otherwise false.
return SYS::ob_eq(self,other)
end ;
init_kind(
val : CODE_KINDS
) is
-- This routine is only usable from within the LIBCHARS class.
priv_kind := val
end ;
-- NOTE All of the routines below return non-void values since all of
-- the components have to be present for self not to be void!!
-- If self were to be void on entry then either a valid value is
-- returned or an exception has been raised. No pre/post
-- conditions are therefore provided for these routines.
kind : CODE_KINDS is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the value of priv_kind.
if void(self) then
return init.priv_kind
else
return priv_kind
end
end ;
collating : REPERTOIRE is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the current repertoire.
if void(self) then
return init.priv_collating
else
return priv_collating
end
end ;
answers : ANSWERS is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the current answers object.
if void(self) then
return init.priv_answers
else
return priv_answers
end
end ;
charmap : REP_MAP is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the current charmap.
if void(self) then
return init.priv_charmap
else
return priv_charmap
end
end ;
resources : RESOURCES is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the current run-time resources.
if void(self) then
return init.priv_resources
else
return priv_resources
end
end ;
sather_lib : LIBCHARS is
-- This routine auto-initialises the default culture/repertoire if
-- necessary and then returns the appropriate char library.
if void(self) then
return init.priv_sather_lib
else
return priv_sather_lib
end
end ;
end ; -- CULTURE
class REP_LIB_LIST
class REP_LIB_LIST is
-- This global class implements the list of currently active repertoire
-- and encoding classes (LIBCHARS). It permits the string and rune classes
-- to index from it rather than have a direct reference to the repertoire.
-- Version 1.0 Apr 99. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 29 Apr 99 kh Original
readonly shared lib_list : FLIST{LIBCHARS} ;
insert(
lib : LIBCHARS
) : BOOL
pre ~void(lib)
post lib_list.contains(lib)
is
-- This routine inserts the given library into the library list,
-- returning true. However, if the library is already present then false
-- is returned!
if void(lib_list) then
lib_list := FLIST{LIBCHARS}::create.push(lib) ;
return true
elsif index(lib) /= CARD::nil then -- a major heap memory error!
return false
else
lib_list := lib_list.push(lib) ;
return true
end
end ;
index(
lib : LIBCHARS
) : CARD
pre ~void(lib)
and ~void(lib_list)
post (result = CARD::nil)
or lib_list.contains(lib)
is
-- This routine returns the index of the argument in the list or
-- CARD::nil if it is not present.
loop
loc_index : CARD := 0.upto!(lib_list.size - 1) ;
if lib = lib_list[loc_index] then
return loc_index
end
end ;
return CARD::nil
end ;
end ; -- REP_LIB_LIST