% $Id: NLS.TEX 1.1 2000/01/24 10:18:53 ska Exp ska $
\section{\label{ssNls}\subsys{nls}}


This subsystem provides an easy access to the information
of the National Language Support (NLS) offered by DOS.
Because there are various different kinds of data, which are to
use in different manners, a wide set of functions are available.


\subsection{Country-Specific Information}

Besides included into the standard NLS implementation of \suppl,
this information is also available on a stand-alone basis by
including the header file \fnam{CNTRY.H} only.

\subsubsection{Design}

DOS stores some information about how to format values of
date, time and currency and what character is the upcased or
lowercased of a character and how characters are sorted.

This various information is stored in several tables and the user
must call various DOS function to actually gain access to this
information. Therefore this subsystem offers a portable way to
retreive this information from DOS, stores some data into an internal
buffer and preprocesses them in order to ease and unify the way the
data is used.

Though, due to the fact that not all data is available on all systems,
the user must probe each individual data, if it is present {\em before}
actually using it. This is true especially for the lower-case table and
the double byte character support.

Warning: The internally used static buffer holding the preprocessed
data does not contain the tables themselves, but pointers to the
real information. This techinique is necessary, because -- unlike the
behaviour and implementation of several tools -- the structures used by
DOS allow different sizes of these tables. SUPPL's implementation is to
be robust, so only pointers are cached.\newline
{\em But:} The information of NLS depends on two global DOS settings:
\begin{enumerate}
\item the selected country code, and
\item the selected code page.
\end{enumerate}
But because both settings usually remain constant during the life-time of
an application, the information is not automatically updated when those
settings are changed. If such condition might happened, the subsystem
must be forced to re-initialized itself, see the paragraphe below.

\subsubsection{Implementation}

The function \tok{Country *nlsInfo(void)} retreives all available data
from DOS and caches the preprocessed data into the static internal
buffer. If the buffer is already filled, the data is not retreived
again. To force the NLS subsystem to re-retreive the data, the function
\tok{Country *nlsNewInfo(void)} is provided.

Warning: One shall not rely on the fact that currently both functions
return the pointer to same internal static buffer all the time.

The functions return a pointer to a buffer of the type \tok{Country}. This
is a structure with the follwing members:
\begin{description}
\item[\tok{country}:] currently active DOS country code
\item[\tok{charset}:] currently active DOS codepage

\item[\tok{uppercaseTbl}:] uppercase table of {\em normal} characters
\item[\tok{uppercaseLen}:] length of uppercase table of {\em normal} characters

\item[\tok{lowercaseTbl}:] lowercase table of {\em normal} characters
\item[\tok{lowercaseLen}:] length of lowercase table of {\em normal} characters

\item[\tok{fupcaseTbl}:] uppercase table of filename characters
\item[\tok{fupcaseLen}:] length of uppercase table of filename characters

\item[\tok{collateTbl}:] collating sequence table of characters
\item[\tok{collateLen}:] length of collating sequence table of characters

\item[\tok{illegalChars}:] table of illegal characters in filenames
\item[\tok{illegalLen}:] number of characters within the \tok{illegalChar}
	table

\item[\tok{inclFirst, inclLast}:] permissible range of valid characters
	within filenames
\item[\tok{exclFirst, exclLast}:] excluded range of valid characters
	within filenames (superceeds the \tok{inclFirst, inclLast} range)

\item[\tok{curSymbol}:] string of currency symbol
\item[\tok{thousendsSep}:] string of thousends separator: the
	character inserted between each third position of the
	integer part of a number (counted from the right)
\item[\tok{decimalSep}:] string of decimal separator: the character
	between the integer and the fraction part of a number
\item[\tok{dateSep}:] string of date separator
\item[\tok{timeSep}:] string of time separator
\item[\tok{listSep}:] string of list separator: the character seperating
	two or more fields or words located on the same line. For instance
	used as the {\em comma} in the so-called Comma Seperated Values (CSV)
	format supported by several spreadsheet applications.

\item[\tok{datefmt}:] format of date:\\ \noindent
	\begin{tableThree}{code}{name}{format}
	0 & USA & mm/dd/yy \\
	1 & Europe & dd/mm/yy \\
	2 & Japan & yy/mm/dd \\
	\end{tableThree}
\item[\tok{timefmt}:] Bit 0 specifies the time format \\ \noindent
	\begin{tableTwo}{value}{format}
	0 & 12-hour clock (AM/PM appended) \\
	1 & 24-hour clock \\
	\end{tableTwo}
\item[\tok{curFormat}:] format of currency symbol \\ \noindent
	\begin{tableThree}{bit}{value}{format}
	0 & 0 & currency symbol preceeds number \\
	0 & 1 & currency symbol follows number \\
	1 & 0 & no space between currency symbol and number \\
	1 & 1 & one space between currency symbol and number \\
	2 & 0 & use settings in bits 0 and 1 \\
	2 & 1 & currency symbol replaces decimal separator \\
	\end{tableThree}

\item[\tok{precision}:] number of digits after decimal point (currency only)

\end{description}

Notes:
\begin{enumerate}
\item A {\em table}, e.g. \tok{uppercaseTbl}, is a far pointer to the
	actual data statically located within the kernel memory.
\item The length of such table may vary. In single-byte character sets,
	meaning that one character is represanted by exactly one byte, there are
	two lengths known: 128 and 256.

	If the length is 128, the table holds the information for characters
	greater or equal to ASCII code 128, which is the so-called Extended
	Character Set. DOS assumes that the lower set, the standard 7-bit
	ASCII characters, can be handled by the program alone easily.
	However to ease the useage of the tables the pointers of them are
	modified so that the indexes match the ASCII code of the character.
	\newline For instance if the upcase table holds 128 bytes, the byte
	at index 0 (zero) contains the uppercased variant of the character
	with the ASCII code #128; therefore the pointer decremented by 128
	in order to let point index 128 to the uppercased variant of
	character #128.

	Pointers of tables holding more than 128 characters are nor
	modified.

	This rule does not apply to table \tok{illegalChars}.

\item If a table is not present, the pointer is \tok{NULL} and its
	length is set to 0 (zero).

\item The {\em string of} members are valid C strings where it is
	ensured that the terminating NUL byte is present.
\end{enumerate}


\subsection{Case-specific Functions}

\subsubsection{Design}

These functions use the function \fct{nlsInfo} to aquire the
upcase table and perform all their activity on top of the
\tok{Country} structure. Therefore these functions suffer the
same problem, if the country-specific information is changed
during life-time of the program. In such case the {\em user}
must manually call function \fct{nlsNewInfo} to ensure that
the internal buffer gets updated!

DOS NLS contains only information how to {\em upcase} characters. The
lowercase table is only supported by certain, as far as I know the
Russian only, NLS. But, interestingly, there are two upcase tables:
One to upcase normal characters used to present words of a text to the
user and one to upcase characters of filenames.

The implementation of \suppl keeps track of the difference, although,
it is not known if there really is a NLS where both tables differ.

Because the upper-case table is the standard table and should be
supported by all NLS environments, all case-insensitive compares
upcase the characters. No function of \suppl will use the
lowercase table, unless explicitly noted.

\subsubsection{Implementation}

All upcase functions case-insensitve compare functions are available
in two variants, one with a \tok{F} in the name and one without it. The
ones with the \tok{F} are using the filename character upcase table,
the other ones the normal table. All functions can securely handle
characters in the range 0..256. Characters outside of this range, e.g.
because a \tok{(char)} value is represanted as a signed integer, are
trimmed into this range\footnote{The upper byte of a character value
is completely ignored.}.
{\bf Warning:} The character \tok{EOF} is usually represanted by \tok{(-1)} and
exceeds the supported limits therefore!

In below table remove the \tok{F} to get the name of the {\em normal}
function. If the name does not contain no \tok{F}, there is no particular
function for filename characters.

\begin{tabTS}
\fct{toLower} & Lowercase a single character. \\
\fct{toFUpper} & Upcase a single character. \\
\fct{memcmpFI} & Compare two memory areas case-insensitively. \\
\fct{_fmemcmpFI} & Compare two far memory areas case-insensitively. \\
\fct{MemiCmp} & Compare two memory areas case-insensitively. \\
\fct{_fMemiCmp} & Compare two far memory areas case-insensitively. \\
\fct{StriCmp} & Compare two strings case-insensitively. \\
\fct{StrUpr} & Upcases the whole string. \\
\fct{MemUpr} & Upcases the whole memory area. \\
\fct{_StrUpr} & Upcases the whole far string. \\
\fct{_MemUpr} & Upcases the whole far memory area. \\
\fct{isodigit} & Tests if the character is an octal digit. \\
\fct{toxdigit} & Transforms a valid hexadecimal digit into
	its binary format. \\
\end{tabTS}

\subsection{Date and Time Functions}

{\Large Note: This part of \suppl  is newly available and
lacks many functionality still!}

DOS C compilers offer many ways to let a programmer aquire the current
time\footnote{\quote{Time} refers to the information consisting of hour,
minute, seconds and, maybe, fractions of seconds here. It is {\em not}
connected to do timing or time/date based arethemtics; though,
arethemtics might be added later on.} and date\footnote{\quote{Date}
refers to an information constructed of day, month and year. The
refernce is the Christian Gregorian calendar, also known as {\sc A.D.}
({\it anno domini}) and {\sc A.C.} (\quote{after Christ}).} and present
this information in a portable way suitable for all compilers.

ANSI C (ISO9899) does include such functions already, they include:
\begin{itemize}
\item \fct{\_dos\_gettime()} and \fct{\_dos\_getdate()} (DOS),
\item \fct{gettime()} and \fct{getdate()} (DOS),
\item \fct{\_bios\_timeofday()} (DOS),
\item \fct{biostime} (DOS),
\item \fct{ftime()} (System V),
\item \fct{time()} (ISO9899),
\item \fct{localtime()} (ISO9899),
\item \fct{gmtime()} (ISO9899).
\end{itemize}
\fct{time()} returns the number of elapsed seconds since
{\large\bf the} epoch, the 01st January 1970 00:00:00 (that's one hour
before 1 o'clock A.M.  :-). \fct{localtime()} and \fct{gmtime()} break
that number into components, such as second, minute, hour, day of month,
month, year, day of week and day of year either of the local timezone or
GMT -- also called UTC especially in Microsoft-influenced environments,
or just {\em standard time}.

The concept of the difference between a {\em local time zone} and GMT is
not very common in DOS-based environments, because traditionally the
clock of IBM-compatible computers are initialized with the local time.

The advantage or disadvantage shall not been discussed here, except that
using GMT would solve many home-brewed and time-based problems, for
instance that some programs go crazy when the admittedly also crazy DST
(Daylight Saving Time) comes into effect and the clock moves one hour
{\em backwards} -- into the past!

Well, basically many DOS programmers ignore robustness, stability and
flexibility and prefer to call the BIOS directly, in order to save a few
bytes. Not only doing do disables the possibility to switch the clock to
GMT, it makes it impossible to use the standard time/date formatting
functions of C. Well, unfortunately DOS based C environments don't
adjuste themselves properly to what DOS offers as country specific
information and simply defaults to usually settings suitable for the
U.S.A.

To make long speech short, this section of NLS support of \suppl  shall
free a programmer from implementing an own time arethmetics and
conversation rules, especially to overcome the problem to actually {\em
know} the differences. Though, as everything the amount of support will
be selectedable at compile-time, e.g.\ whether or not to support time
zones and computer clocks running in GMT.

\subsubsection{Design}

A many people differ between \quote{date} and \quote{time}\footnote{Unless
quoted the word {\em time} shall refer to an information of either
\quote{date} or \quote{time} meaning, or even combine both.} in the
context of to specify a concrete spot in the ever running time line.
\quote{date} refers to a day, whereas \quote{time} specifies a
particular spot of a particular day.

Whereas the Unix-based environments always use one structure or value to
indentify both parts at once, IBM-compatible computers offer both values
via different API functions.

In the sense to keep a limited problem at a limited range, so when a
program does use the \quote{time} only, there is no need to call up both
API functions, only to discard one part later on. Therefore \suppl
offers divided interfaces for \quote{time} and \quote{date}.

However, all time functions of \suppl  use the same user structure to
pass in and back information. This shall help to minimize the overhead
when \quote{date} and \quote{time} are used individually and combined
within the same program, because the underlying functions are the same,
because they can act over the same structure. It is no longer necessary
to write one function acting over \quote{time}-only structure and and
one over the combined structure. As a consequence the members of such
structure are not initialized all time, because when the time structure
is initialized by a \quote{time}-only function, the \quote{date}-only
members are left alone. The programmer must keep track of the
initialization state.

To help to keep a limited problem at a limit, \suppl  offers two sets of
time functions, one set is aware of time zones and the other one ignores
any timezones completely and just use the time value as it is aquired
from the system.

It is also noteworth that \suppl  basically only offers the broken-up
form to keep a time value, meaning that hour, minute, day etc. are
stored in individual members of the \tok{nlstime} structure.
When doing much time-based arethmetics this becomes heavily inefficient,
so that there is an alternate format. This format supports arethmetics
better, but to extract the individual parts (hour, minute, day etc.)
becomes more inefficient. Because \suppl  cannot automatically adjust
itself to use the most efficient format, the programmer must do so.

\subsubsection{Implementation}

All global symbols begin with either \fct{nls}, \fct{Nls} or
\fct{NLS}.

\subsubsubsection{Macros and Types}

\begin{tabTS}
\tok{nlstime} & The structure type containing a time in its broken-up
format, the members and their ranges of values are:
\begin{description}
\item[\fct{ti_hour}] hour\footnote{Initialized if \quote{time}-only or
	combined init function was called.} -- 0 \ldots 23
\item[\fct{ti_minute}] minute\samefootnote -- 0 \ldots 59
\item[\fct{ti_second}]  seconds\samefootnote -- 0 \ldots 59
\item[\fct{ti_hundred}] hundreds of seconds\samefootnote -- 0 \ldots 99
\item[\fct{ti_weekday}] day of week\footnote{Initialized by
	particular functions only.} -- 0 \ldots 6, 0 == Sunday, \suppl  functions
	also accepts 7 == Sunday, but always return Sunday as 0
\item[\fct{ti_day}] day\footnote{Initialized if \quote{date}-only or
	combined init function was called.} -- 1 \ldots 31
\item[\fct{ti_month}] month\samefootnote -- 1 \ldots 12
\item[\fct{ti_year}] full year\samefootnote -- 1980 \ldots 2099\footnote{Limited
	by how IBM-compatible computers stores the year.}
\end{itemize}
\end{tabTS}


\subsubsubsection{Macros and Types}

\begin{tabTS}

\fct{nlsCurTime} & Initializes the \quote{time}-members -- hour, minute,
	seconds and hundreds -- with the current time. \\
\fct{nlsCurDate} & Initializes the \quote{date}-members -- day, month,
	year and day of week -- with the current time. \\

\end{tabTS}
