116 lines
2.5 KiB
C
116 lines
2.5 KiB
C
|
/*
|
|||
|
** dbcs.c - DBCS functions for DOS apps.
|
|||
|
**
|
|||
|
** Written by RokaH and DavidDi.
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
/* Headers
|
|||
|
**********/
|
|||
|
|
|||
|
#include <dos.h>
|
|||
|
#include <ctype.h>
|
|||
|
|
|||
|
#include <dbcs.h>
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
** int IsDBCSLeadByte(unsigned char uch);
|
|||
|
**
|
|||
|
** Check to see if a character is a DBCS lead byte.
|
|||
|
**
|
|||
|
** Arguments: uch - charcter to examine
|
|||
|
**
|
|||
|
** Returns: int - 1 if the character is a DBCS lead byte. 0 if not.
|
|||
|
**
|
|||
|
** Globals: none
|
|||
|
*/
|
|||
|
int IsDBCSLeadByte(unsigned char uch)
|
|||
|
{
|
|||
|
static unsigned char far *DBCSLeadByteTable = 0;
|
|||
|
union REGS inregs, outregs;
|
|||
|
struct SREGS segregs;
|
|||
|
unsigned char far *puch;
|
|||
|
|
|||
|
if (DBCSLeadByteTable == 0)
|
|||
|
{
|
|||
|
/*
|
|||
|
** Get DBCS lead byte table. This function has been supported since
|
|||
|
** DBCS MS-DOS 2.21.
|
|||
|
*/
|
|||
|
inregs.x.ax = 0x6300;
|
|||
|
intdosx(&inregs, &outregs, &segregs);
|
|||
|
|
|||
|
FP_OFF(DBCSLeadByteTable) = outregs.x.si;
|
|||
|
FP_SEG(DBCSLeadByteTable) = segregs.ds;
|
|||
|
}
|
|||
|
|
|||
|
/* See if the given byte is in any of the table's lead byte ranges. */
|
|||
|
for (puch = DBCSLeadByteTable; puch[0] || puch[1]; puch += 2)
|
|||
|
if (uch >= puch[0] && uch <= puch[1])
|
|||
|
return(1);
|
|||
|
|
|||
|
return(0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
** unsigned char *AnsiNext(unsigned char *puch);
|
|||
|
**
|
|||
|
** Moves to the next character in a string.
|
|||
|
**
|
|||
|
** Arguments: puch - pointer to current location in string
|
|||
|
**
|
|||
|
** Returns: char * - Pointer to next character in string.
|
|||
|
**
|
|||
|
** Globals: none
|
|||
|
**
|
|||
|
** N.b., if puch points to a null character, AnsiNext() will return puch.
|
|||
|
*/
|
|||
|
unsigned char far *AnsiNext(unsigned char far *puch)
|
|||
|
{
|
|||
|
if (*puch == '\0')
|
|||
|
return(puch);
|
|||
|
else if (IsDBCSLeadByte(*puch))
|
|||
|
puch++;
|
|||
|
|
|||
|
puch++;
|
|||
|
|
|||
|
return(puch);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
** unsigned char *AnsiPrev(unsigned char *psz, unsigned char *puch);
|
|||
|
**
|
|||
|
** Moves back one character in a string.
|
|||
|
**
|
|||
|
** Arguments: psz - pointer to start of string
|
|||
|
** puch - pointer to current location in string
|
|||
|
**
|
|||
|
** Returns: char * - Pointer to previous character in string.
|
|||
|
**
|
|||
|
** Globals: none
|
|||
|
**
|
|||
|
** N.b., if puch <= psz, AnsiPrev() will return psz.
|
|||
|
**
|
|||
|
** This function is implemented in a very slow fashion because we do not wish
|
|||
|
** to trust that the given string is necessarily DBCS "safe," i.e., contains
|
|||
|
** only single-byte characters and valid DBCS characters. So we start from
|
|||
|
** the beginning of the string and work our way forward.
|
|||
|
*/
|
|||
|
unsigned char far *AnsiPrev(unsigned char far *psz, unsigned char far *puch)
|
|||
|
{
|
|||
|
unsigned char far *puchPrevious;
|
|||
|
|
|||
|
do
|
|||
|
{
|
|||
|
puchPrevious = psz;
|
|||
|
psz = AnsiNext(psz);
|
|||
|
} while (*psz != '\0' && psz < puch);
|
|||
|
|
|||
|
return(puchPrevious);
|
|||
|
}
|
|||
|
|
|||
|
|