NLS.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:19k
- /****************************************************************/
- /* */
- /* nls.c */
- /* DOS-C */
- /* */
- /* National Languge Support functions and data structures */
- /* */
- /* Copyright (c) 1995, 1996 */
- /* Pasquale J. Villani */
- /* All Rights Reserved */
- /* */
- /* Copyright (c) 1995, 1996 */
- /* Steffen Kaiser */
- /* All Rights Reserved */
- /* */
- /* This file is part of DOS-C. */
- /* */
- /* 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. */
- /****************************************************************/
- /* $Logfile: C:/dos-c/src/kernel/nls.c_v $ */
- #ifdef VERSION_STRINGS
- static BYTE *RcsId = "$Header: C:/dos-c/src/kernel/nls.c_v 1.4 04 Jan 1998 23:15:16 patv $";
- #endif
- /* $Log: C:/dos-c/src/kernel/nls.c_v $
- *
- * Rev 1.4 04 Jan 1998 23:15:16 patv
- * Changed Log for strip utility
- *
- * Rev 1.3 16 Jan 1997 12:46:54 patv
- * pre-Release 0.92 feature additions
- *
- * Rev 1.2 29 May 1996 21:03:46 patv
- * bug fixes for v0.91a
- *
- * Rev 1.1 19 Feb 1996 4:34:46 patv
- * Corrected typo
- *
- * Rev 1.0 19 Feb 1996 3:21:46 patv
- * Added NLS, int2f and config.sys processing
- */
- /* $EndLog$ */
- #include "../../hdr/portab.h"
- #include "globals.h"
- extern UWORD internalUpcase(UWORD c);
- #ifndef lint
- static char const rcsid[] =
- "$Id$";
- #endif
- /* 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
- struct ctryInfo { /* Country Information DOS-38 */
- WORD dateFmt; /* 0: USA, 1: Europe, 2: 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, 1: behind number
- bit 1: currency string and number are separated by a space; 0: No, 1: Yes
- */
- BYTE prescision; /* */
- BYTE timeFmt; /* time format: 0: 12 hours; 1: 24 houres */
- VOID (FAR *upCaseFct)(VOID); /* far call to a function mapping character in register AL */
- char dataSep[2]; /* ASCIZ of separator in data records */
- };
- struct _VectorTable
- {
- VOID FAR *Table;
- BYTE FnCode;
- };
- struct _NlsInfo
- {
- struct extCtryInfo
- {
- BYTE reserved[8];
- BYTE countryFname[64];
- WORD sysCodePage;
- WORD nFnEntries;
- struct _VectorTable VectorTable[6];
-
- /* Extended Country Information DOS-65-01 */
- WORD countryCode; /* current COUNTRY= code */
- WORD codePage; /* current code page (CP) */
- struct ctryInfo nlsCtryInfo;
- } nlsExtCtryInfo;
- /* characters of Yes/No prompt for DOS-65-23 */
- char yesCharacter;
- char noCharacter;
- /* upcased characters for ECS-ASCII > 0x7f for DOS-65-02 */
- WORD upNCsize; /* number of entries in the following array */
- char upNormCh[128];
- /* upcased characters for ECS-ASCII > 0x7f for file names for DOS-65-04 */
- WORD upFCsize; /* number of entries in the following array */
- char upFileCh[128];
- /* collating sequence for ECS-ASCII 0..0xff for DOS-65-06 */
- WORD collSize; /* number of entries in the following array */
- char collSeq[256];
- /* DBC support for DOS-65-07 */
- WORD dbcSize; /* number of entries in the following array */
- /* char dbcTable[1024]; no DBC support */
- WORD dbcEndMarker; /* contains always 0 */
- /* in file names permittable characters for DOS-65-05 */
- struct chFileNames {
- WORD fnSize; /* 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 fnSeparators[14];
- } nlsFn;
- } nlsInfo
- #ifdef INIT_NLS_049
- = /* let's initialize it with values for Germany */
- #include "049-437.nls"
- #else
- = /* let's initialize it with default values (USA) */
- #include "001-437.nls"
- #endif
- ;
- #define normalCh nlsInfo.upNormCh
- #define fileCh nlsInfo.upFileCh
- #define yesChar nlsInfo.yesCharacter
- #define noChar nlsInfo.noCharacter
- #define PathSep(c) ((c)=='/'||(c)=='\')
- #define DriveChar(c) (((c)>='A'&&(c)<='Z')||((c)>='a'&&(c)<='z'))
- /* COUNTRY.SYS structures */
- struct CpiHeader
- {
- BYTE name[8]; /* signature */
- BYTE reserved[8];
- WORD nPointers; /* size of following array */
-
- struct
- {
- BYTE pointerType; /* always 1 */
- DWORD offset; /* offset to data */
- } pointer[1];
- };
- struct CountryRecord
- {
- WORD length; /* size of record */
- WORD country; /* country code */
- WORD codePage; /* code page */
- WORD reserved[2];
- DWORD subCountryOffset; /* offset to data record */
- };
- struct CountryTableDescr
- {
- WORD length; /* size of structure */
- WORD id; /* table type id */
- DWORD offset; /* offset to table data */
- };
- /* 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
-
- COUNT NlsFuncInst(VOID)
- {
- BYTE cNlsRet;
- asm {
- xor bx,bx
- mov ax,1400h
- int 2Fh
- mov cNlsRet,al
- }
- /* Return the al register as sign extended: */
- /* 0 == not installed, ok to install */
- /* 1 == not installed, not ok to install */
- /* -1 == installed */
- return cNlsRet;
- }
- BOOL
- GetGlblCodePage(UWORD FAR *ActvCodePage, UWORD FAR *SysCodePage)
- {
- *ActvCodePage = nlsInfo.nlsExtCtryInfo.codePage;
- *SysCodePage = nlsInfo.nlsExtCtryInfo.sysCodePage;
- return TRUE;
- }
- BOOL
- SetGlblCodePage(UWORD FAR *ActvCodePage, UWORD FAR *SysCodePage)
- {
- nlsInfo.nlsExtCtryInfo.codePage = *ActvCodePage;
- nlsInfo.nlsExtCtryInfo.sysCodePage = *SysCodePage;
- return TRUE;
- }
- UWORD SetCtryInfo(UBYTE FAR *lpShrtCode, UWORD FAR *lpLongCode,
- BYTE FAR *lpTable, UBYTE *nRetCode)
- {
- UWORD CntryCode;
- UBYTE nNlsEntry;
- UWORD uSegTable, uOffTable;
- UBYTE nLclRet;
- /* Get the Country Code according to the DOS silly rules. */
- if(0xff != *lpShrtCode)
- CntryCode = *lpShrtCode;
- else
- CntryCode = *lpLongCode;
- /* If it's the same country code as what's installed, just */
- /* return because there's nothing to do. */
- if(CntryCode == nlsInfo.nlsExtCtryInfo.countryCode)
- {
- *nRetCode = 0;
- return CntryCode;
- }
- /* Check if nlsfunc is installed */
- if(NlsFuncInst() >= 0)
- {
- *nRetCode = 0xff;
- return 0xffff;
- }
- /* Get the country information from nlsfunc */
- uSegTable = FP_SEG(lpTable);
- uOffTable = FP_OFF(lpTable);
- asm {
- push ds
- mov bx,CntryCode
- mov ax,uSegTable
- mov dx,uOffTable
- mov ds,ax
- mov ax,1404h
- int 2Fh
- pop ds
- mov CntryCode,bx
- mov nLclRet,al
- }
- *nRetCode = nLclRet;
- return CntryCode;
- }
- UWORD GetCtryInfo(UBYTE FAR *lpShrtCode, UWORD FAR *lpLongCode,
- BYTE FAR *lpTable)
- {
- UWORD CntryCode;
- if(0xff != *lpShrtCode)
- CntryCode = *lpShrtCode;
- else
- CntryCode = *lpLongCode;
- fbcopy((BYTE FAR *)&nlsInfo.nlsExtCtryInfo.nlsCtryInfo,
- lpTable, sizeof(struct ctryInfo));
- return nlsInfo.nlsExtCtryInfo.countryCode;
- }
- BOOL
- ExtCtryInfo(UBYTE nOpCode, UWORD CodePageID, UWORD InfoSize, VOID FAR *Information)
- {
- VOID FAR *lpSource;
- COUNT nIdx;
- if(0xffff != CodePageID)
- {
- UBYTE nNlsEntry;
- if(NlsFuncInst() >= 0)
- return FALSE;
- asm {
- mov bp,word ptr nOpCode
- mov bx,CodePageID
- mov si,word ptr Information+2
- mov ds,si
- mov si,word ptr Information
- mov ax,1402h
- int 2Fh
- cmp al,0
- mov nNlsEntry,al
- }
- if(0 != nNlsEntry)
- return FALSE;
- return TRUE;
- }
- CodePageID = nlsInfo.nlsExtCtryInfo.codePage;
- for(nIdx = 0; nIdx < nlsInfo.nlsExtCtryInfo.nFnEntries; nIdx++)
- {
- if(nlsInfo.nlsExtCtryInfo.VectorTable[nIdx].FnCode == nOpCode)
- {
- BYTE FAR *bp = Information;
- lpSource = nlsInfo.nlsExtCtryInfo.VectorTable[nIdx].Table;
- if (nOpCode == 1)
- {
- bp++; // first byte unused
- *bp = (BYTE)(sizeof(struct ctryInfo) + 4);
- bp += 2;
- fbcopy(lpSource, bp, InfoSize > 3? InfoSize - 3 : 0);
- } else {
- *bp++ = nOpCode;
- *((VOID FAR **)bp) = lpSource;
- }
- return TRUE;
- }
- }
- return FALSE;
- }
- UWORD internalUpcase(UWORD c)
- {
- if (!(c & 0x80)) return c;
- return (c & 0xff00) | (nlsInfo.upNormCh[c & 0x7f] & 0xff);
- }
- char upMChar(UPMAP map, char ch)
- /* upcase character ch according to the map */
- { return (ch >= 'a' && ch <= 'z')? ch + 'A' - 'a':
- ((unsigned)ch > 0x7f? map[ch & 0x7f]: ch);
- }
- VOID upMMem(UPMAP map, char FAR *str, unsigned len)
- { REG unsigned c;
- if(len) do {
- if((c = *str) >= 'a' && c <= 'z')
- *str += 'A' - 'a';
- else if(c > 0x7f)
- *str = map[c & 0x7f];
- ++str;
- } while(--len);
- }
- BYTE yesNo(char ch) /* returns: 0: ch == "No", 1: ch == "Yes", 2: ch crap */
- {
- ch = upMChar(normalCh, ch);
- if(ch == noChar)
- return 0;
- if(ch == yesChar)
- return 1;
- return 2;
- }
- char upChar(char ch) /* upcase a single character */
- {
- return upMChar(normalCh, ch);
- }
- VOID upString(char FAR *str) /* upcase a string */
- {
- upMMem(normalCh, str, fstrlen(str));
- }
- VOID upMem(char FAR *str, unsigned len) /* upcase a memory area */
- {
- upMMem(normalCh, str, len);
- }
- char upFChar(char ch) /* upcase a single character for file names */
- {
- return upMChar(fileCh, ch);
- }
- VOID upFString(char FAR *str) /* upcase a string for file names */
- {
- upMMem(fileCh, str, fstrlen(str));
- }
- VOID upFMem(char FAR *str, unsigned len) /* upcase a memory area for file names */
- {
- upMMem(fileCh, str, len);
- }
- /* LoadCountryInfo():
- *
- * Searches a file in the COUNTRY.SYS format for an entry
- * matching the specified code page and country code, and loads
- * the corresponding information into memory. If code page is 0,
- * the default code page for the country will be used.
- *
- * Returns TRUE if successful, FALSE if not.
- */
-
- BOOL LoadCountryInfo(char FAR *filename, WORD ctryCode, WORD codePage)
- {
- struct CpiHeader hdr;
- struct CountryRecord ctry;
- struct CountryTableDescr ct;
- COUNT i, nCountries, nSubEntries;
- ULONG currpos;
- int rc = FALSE;
- COUNT file;
- if ((file = dos_open(filename, 0)) < 0)
- return rc;
-
- if (dos_read(file, &hdr, sizeof hdr) == sizeof hdr)
- {
- /* check signature */
- if (!fstrncmp(hdr.name, "377COUNTRY", 8))
- {
- dos_lseek(file, hdr.pointer[0].offset, 0);
- dos_read(file, &nCountries, sizeof nCountries);
- /* search for matching country record */
- for (i = 0; i < nCountries; i++)
- {
- if (dos_read(file, &ctry, sizeof ctry) != sizeof ctry)
- break;
- if (ctry.country == ctryCode && (!codePage || ctry.codePage == codePage))
- {
- /* found country - now load the tables */
- dos_lseek(file, ctry.subCountryOffset, 0);
- dos_read(file, &nSubEntries, sizeof nSubEntries);
- currpos = ctry.subCountryOffset + sizeof nSubEntries;
- for (i = 0; i < nSubEntries; i++)
- {
- dos_lseek(file, currpos, 0);
- if (dos_read(file, &ct, sizeof ct) != sizeof ct)
- break;
- currpos += ct.length + sizeof ct.length;
- ReadCountryTable(file, ct.id, ct.offset + 8);
- }
-
- if (i == nSubEntries) rc = TRUE;
- break;
- }
- }
- }
- }
- dos_close(file);
- return rc;
- }
- /* ReadCountryTable():
- *
- * Loads a country information table.
- */
- static BOOL ReadCountryTable(COUNT file, WORD id, ULONG offset)
- {
- VOID *buf; /* where to load the information */
- UWORD maxSize; /* max number of bytes to read */
- UWORD length; /* length of table in file */
- BOOL rc = TRUE;
- switch (id)
- {
- case 1: /* extended country information */
- buf = &nlsInfo.nlsExtCtryInfo.countryCode;
- maxSize = sizeof(struct ctryInfo) + sizeof(WORD) * 2;
- break;
- case 2: /* uppercase table */
- buf = &normalCh[0];
- maxSize = sizeof normalCh;
- break;
- case 4: /* filename uppercase table */
- buf = &fileCh[0];
- maxSize = sizeof fileCh;
- break;
- case 5: /* filename terminator table */
- buf = &nlsInfo.nlsFn.dummy1;
- maxSize = sizeof(struct chFileNames) - sizeof(WORD);
- break;
- case 6: /* collating sequence table */
- buf = &nlsInfo.collSeq[0];
- maxSize = sizeof nlsInfo.collSeq;
- break;
- default: /* unknown or unsupported table - ignore */
- buf = 0;
- break;
- }
- if (buf)
- {
- dos_lseek(file, offset, 0);
- dos_read(file, &length, sizeof length);
-
- if (length > maxSize) length = maxSize;
-
- if (dos_read(file, buf, length) != length)
- rc = FALSE;
- if (id == 1)
- nlsInfo.nlsExtCtryInfo.nlsCtryInfo.upCaseFct = CharMapSrvc;
- }
- return rc;
- }