FreeDOS/hdr/nls.h
Jim Tabor d7060f0ace Update CVS to 2020
git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@8 6ac86273-5f31-0410-b378-82cca8765d1b
2000-05-08 23:01:16 +00:00

371 lines
15 KiB
C

/****************************************************************/
/* */
/* NLS.H */
/* FreeDOS */
/* */
/* National Language Support data structures */
/* */
/* Copyright (c) 1995, 1996, 2000 */
/* Steffen Kaiser */
/* All Rights Reserved */
/* */
/* This file is part of FreeDOS. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C 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 */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
/* one byte alignment */
#if defined(_MSC_VER)
#define asm __asm
#pragma pack(1)
#elif defined(_QC) || defined(__WATCOM__)
#pragma pack(1)
#elif defined(__ZTC__)
#pragma ZTC align 1
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
#pragma option -a-
#endif
/*
* Description of the organization of NLS information -- 2000/02/13 ska
*
* Glossar:
* NLS package -- NLS information incl. any code required to access or
* correctly interprete this particular information
*
* Abbreviation:
* (NLS) pkg -- NLS package
*
* The code included into the kernel does "only" support NLS packages
* structurally compatible with the one of the U.S.A. / CP437.
* I guess that most NLS packages has been tweaked to be compatible
* so that this is not a real limitation, but for all other packages
* the external NLSFUNC can supply every piece of code necessary.
* To allow this the interface between the kernel and NLSFUNC has been
* extended; at same time the interface has been reduced, because some
* of the API functions do not seem to offer any functionality required
* for now. This, however, may be a misinterpretation because of
* lack of understanding.
*
* The supported structure consists of the following assumptions:
* 1) The pkg must contain the tables 2 (Upcase character), 4
* (Upcase filename character) and 5 (filename termination
* characters); because they are internally used.
* 2) The tables 2 and 4 must contain exactly 128 (0x80) characters.
* The character at index 0 corresponses to character 128 (0x80).
* The characters in the range of 0..0x7f are constructed out of
* the 7-bit US-ASCII (+ control characters) character set and are
* upcased not through the table, but by the expression:
* (ch >= 'a' && ch <= 'z')? ch - 'a' + 'A': ch
* with: 'a' == 97; 'z' == 122; 'A' == 65
*
* It seems that pure DOS can internally maintain two NLS pkgs:
* NLS#1: The hardcoded pkg of U.S.A. on CP437, and
* NLS#2: the pkg loaded via COUNTRY= from within CONFIG.SYS.
* I do interprete this behaviour as follows:
* CONFIG.SYS is read in more passes; before COUTRY= can be evaluated,
* many actions must be performed, e.g. to load kernel at all, open
* CONFIG.SYS and begin reading. The kernel requires at least one
* NLS information _before_ COUNTRY= has been evaluated - the upcase
* table. To not implement the same function multiple times, e.g.
* to upcase with and without table, the kernel uses the default
* NLS pkg until a more appropriate can be loaded and hopes that
* the BIOS (and the user) can live with its outcome.
* Though, theoretically, the hardcoded NLS pkg could be purged
* or overwritten once the COUNTRY= statement has been evaluated.
* It would be possible that this NLS pkg internally performs different
* purposes, for now this behaviour will be kept.
*
* The current implementation extendeds the above "two maintained
* NLS pkgs" into that the kernel chains all NLS pkgs loaded in
* memory into one single linked list. When the user does neither
* wants to load other NLS pkgs without executing NLSFUNC and the
* loaded NLS pkgs do not contain code themselves, no other code is
* required, but some memory to store the NLS pkgs into.
*
* Furthermore, because the kernel needs to include the code for the
* hardcoded NLS pkg anyway, every NLS pkg can use it; so only
* NLS pkgs that structurally differ from U.S.A./CP437 actually need
* to add any code and residently install the MUX handler for NLSFUNC.
* This technique reduces the overhead calling the MUX handler, when
* it is not needed.
*
* The kernel can be instructed to pass any subfunction of DOS-65 to
* MUX-14-02, including the character upcase subfunctions 0x20-0x22 and
* 0xA0-0xA2 as well as 0x23 (yes/no response). That way upcase table can
* be supported (by reducing performance) that do not contain exactly 128
* characters or where the lower portion is not constructed from the 7-bit
* US-ASCII character set.
* To do so, each NLS pkg contains some flags specifying if to pass a
* set of subfunctions to MUX-14-02, the sets include:
* set#1: filename character upcase 0xA0-0xA2
* set#2: character upcase 0x20-0x22
* set#3: yes/no response 0x23
* set#4: Extended Country Information (Includes DOS-38)
* set#5: Anything else (usually picks a pointer from an array)
*
* Win9x supports to change the individual portions of a NLS pkg
* through DOS-65-00; also there are no references what happens when
* a program changes the areas addressed by returned pointers. The
* current implementation does _not_ support changes of the NLS pkg
* except by invoking DOS-38 (Set Country Code) or DOS-66 (Set Codepage).
* Future implementations might offer this ability; to reduce the
* overhead introduced by this feature, the macro NLS_MODIFYABLE_DATA
* enables the appropriate code.
* NLS_MODIFYABLE_DATA is *disabled* by default.
*
* The tables 2 and 4 (upcase tables) are relatively accessed often,
* but theoretically these tables could be loacted at any position
* of the pointer array. If the macro NLS_REORDER_POINTERS is enabled,
* both NLSFUNC and the internal loader will reorder the pointers
* array so that mandatory tables are located at predictable indexes.
* This removes that the kernel must search for the table when
* one of the DOS-65-[2A]x function is called or a filename has been
* passed in (which must be uppercased to be suitable for internal
* purpose). However, when some program try to tweak the internal
* tables this assumption could be wrong.
* NLS_REORDER_POINTERS is *enabled* by default.
*
* A second performance boost can be achieved, if the kernel shall
* support *only* NLS pkgs that apply to the structure mentioned above,
* thus, contain only characters 0x80-0xFF and the range 0x00-0x7F
* is upcased as 7-bit US-ASCII. In this case when upcasing the
* NLS pkg is bypassed at all, but cached pointers are used, which
* point directly to the upcased characters. Because I don't know
* existing NLS pkgs, this feature may be not very trustworthy; also
* when the NLS pkg is switched bypassing DOS, the cached pointers
* won't be updated, also by enabling this macro the MUX-flags are
* ignored for the sub-functions DOS-65-[2A][0-2], therefore:
* NLS_CACHE_POINTERS is *disabled* by default.
*/
/* Define if some user program possibly modifies the value of the internal
tables or the DOS-65-00 (Set Country Information) API function
is to be supported. */
/* Currently unimplemented! -- 2000/02/13 ska*/
/* #define NLS_MODIFYABLE_DATA */
/* Define if the pointer array shall be reordered to allow a quick
access to often used and mandatoryly present tables. */
#define NLS_REORDER_POINTERS
/* Define if the kernel is to cache the time-consuming search results.
Doing so could lead to imporper functionality, if the active
codepage or country ID is changed bypassing the DOS API. */
/* #define NLS_CACHE_POINTERS */
/*
* How the kernel and NLSFUNC communicate with each other
*/
/* Must be returned by NLSFUNC upon MUX-14-00 */
#define NLS_FREEDOS_NLSFUNC_ID 0x534b
/* MUX-14 subfunction called by the kernel to load a specific
NLS package */
#define NLS_NLSFUNC_LOAD_PKG 0x4b
/* MUX-14 subfunction called when to externally upcase */
#define NLS_NLSFUNC_UP 0x61
/* MUX-14 subfunction called when to externally upcase filenames */
#define NLS_NLSFUNC_FUP 0x69
/* Internally used to represent DOS-38 */
#define NLS_DOS_38 0x7365
/* MUX-14 subfunction called when to check yes/nochar */
#define NLS_NLSFUNC_YESNO 0x72
/* Flags for the communication with NLSFUNC */
#define NLS_FLAG_INFO 0x001
#define NLS_FLAG_POINTERS 0x002
#define NLS_FLAG_YESNO 0x004
#define NLS_FLAG_UP 0x008
#define NLS_FLAG_FUP 0x010
/* To ease the maintainance this header file is included to
a) define the "normal" structures, where all the non-fixed size
arrays are noted with length "1", and
b) define the hardcoded NLS package for U.S.A. -- CP437
If the macro NLS_HARDCODED is defined, the structures are modifed
to result into structures with the correct length.
When NLS_NO_VARS is defined, no prototypes of the global
variables are included, useful in sources defining the hardcoded
information, but require the normal types, too.
*/
#ifndef NLS_HARDCODED
/* Use the default of length == 1 */
#define NLS_POINTERS 1
#define NLS_FNAMSEPS 1
#define NLS_DBCSENTR 1
#define __join(a,b) a
#define mkName(a) a
#else
#define __join(a,b) a##b
#define mkName(a) __join(a,NLS_HARDCODED)
#endif
/* No codepage / country code given */
#define NLS_DEFAULT ((UWORD)-1)
#ifndef NLS_HARDCODED
/*
* This is the data in the exact order returned by DOS-65-01
*/
struct nlsExtCtryInfo
{
UBYTE subfct; /* always 1 */
WORD size; /* size of this structure
without this WORD itself */
WORD countryCode; /* current country code */
WORD codePage; /* current code page (CP) */
/*
* This is the data in the exact order as to return on
* DOS-38; it is also the most (important) part of DOS-65-01
*/
/* Note: The ASCIZ strings might become
a totally different understanding with
DBCS (Double Byte Character Support) */
WORD dateFmt; /* order of portions of date
0: mm/dd/yyyy (USA)
1: dd/mm/yyyy (Europe)
2: yyyy/mm/dd (Japan)
*/
char curr[5]; /* ASCIZ of currency string */
char thSep[2]; /* ASCIZ of thousand's separator */
char point[2]; /* ASCIZ of decimal point */
char dateSep[2]; /* ASCIZ of date separator */
char timeSep[2]; /* ASCIZ of time separator */
BYTE currFmt; /* format of currency:
bit 0: currency string is placed
0: before number
1: behind number
bit 1: currency string and number are
separated by a space
0: No
1: Yes
bit 2: currency string replaces decimal
sign
0: No
1: Yes
*/
BYTE prescision; /* of monetary numbers */
BYTE timeFmt; /* time format:
0: 12 hours (append AM/PM)
1: 24 houres
*/
VOID(FAR * upCaseFct) (VOID); /* far call to a function mapping the
character in register AL */
char dataSep[2]; /* ASCIZ of separator in data records */
};
struct nlsPointerInf { /* Information of DOS-65-0X is usually addressed
by a pointer */
UBYTE subfct; /* number of the subfunction */
VOID FAR *pointer; /* the pointer to be returned when the subfunction
of DOS-65 is called (Note: won't work for
subfunctions 0, 1, 0x20, 0x21, 0x22, 0x23,
0xA0, 0xA1,& 0xA2 */
};
#endif
struct mkName(nlsPackage) { /* the contents of one chain item of the
list of NLS packages */
struct nlsPackage FAR *nxt; /* next item in chain */
unsigned muxCallingFlags; /* combination of NLS_FLAGS-* */
struct nlsExtCtryInfo cntryInfo;
char yeschar, nochar; /* yes / no character DOS-65-23 */
unsigned numSubfct; /* number of supported sub-functions */
struct nlsPointerInf nlsPointer[NLS_POINTERS]; /* grows dynamically */
};
struct mkName(nlsDBCS) {
UWORD numEntries;
UWORD dbcsTbl[NLS_DBCSENTR];
};
#ifndef NLS_HARDCODED
struct nlsCharTbl {
/* table containing a list of characters */
WORD numEntries; /* number of entries of this table.
If <= 0x80, the first element of
the table corresponse to character 0x80 */
unsigned char tbl[1]; /* grows dynamically */
};
struct nlsCharTbl128{
WORD numEntries;
unsigned char tbl[128];
};
struct nlsCharTbl256{
WORD numEntries;
unsigned char tbl[256];
};
#endif
/* in file names permittable characters for DOS-65-05 */
struct mkName(nlsFnamTerm) {
WORD size; /* size of this structure */
BYTE dummy1;
char firstCh,
lastCh; /* first, last permittable character */
BYTE dummy2;
char firstExcl,
lastExcl; /* first, last excluded character */
BYTE dummy3;
BYTE numSep; /* number of file name separators */
char separators[NLS_FNAMSEPS]; /* grows dynamically */
};
#ifndef NLS_NO_VARS
struct mkName(nlsInfoBlock) { /* This block contains all information
shared by the kernel and the external NLSFUNC program */
char FAR *fname; /* filename from COUNTRY= */
UWORD sysCodePage; /* system code page */
struct nlsPackage FAR *actPkg; /* current NLS package */
#ifdef NLS_CACHE_POINTERS
unsigned char FAR *fnamUpTable; /* upcase table for filenames */
unsigned char FAR *upTable; /* normal upcase table */
#endif
struct mkName(nlsPackage) chain; /* first item of info chain --
hardcoded U.S.A. */
};
extern struct mkName(nlsInfoBlock) nlsInfo;
extern struct mkName(nlsFnamTerm) nlsFnameTermHardcodedTable;
extern struct mkName(nlsDBCS) nlsDBCSHardcodedTable;
extern struct __join(nlsCharTbl,128) nlsUpHardcodedTable;
extern struct __join(nlsCharTbl,128) nlsFnameUpHardcodedTable;
extern struct __join(nlsCharTbl,256) nlsCollHardcodedTable;
#endif
#undef NLS_POINTERS
#undef NLS_FNAMSEPS
#undef NLS_DBCSENTR
#undef __join(a,b)
#undef mkName(a)
/* standard alignment */
#if defined (_MSC_VER) || defined(_QC) || defined(__WATCOMC__)
#pragma pack()
#elif defined (__ZTC__)
#pragma ZTC align
#elif defined(__TURBOC__) && (__TURBOC__ > 0x202)
#pragma option -a.
#endif