645 lines
17 KiB
C
645 lines
17 KiB
C
/* nls.c */
|
|
/*****************************************************************************/
|
|
/* AS-Portierung */
|
|
/* */
|
|
/* Abhandlung landesspezifischer Unterschiede */
|
|
/* */
|
|
/* Historie: 16. 5.1996 Grundsteinlegung */
|
|
/* 28. 7.1999 %T ist Abkuerzung fuer %H:%M:%S */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
#undef DEBUG_NLS
|
|
|
|
#include "stdinc.h"
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <ctype.h>
|
|
|
|
#ifdef LOCALE_NLS
|
|
#include <locale.h>
|
|
#include <langinfo.h>
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
#define INCL_DOSNLS
|
|
#include <os2.h>
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
#include <dos.h>
|
|
#endif
|
|
|
|
#include "strutil.h"
|
|
|
|
#include "nls.h"
|
|
|
|
CharTable UpCaseTable; /* Umsetzungstabellen */
|
|
CharTable LowCaseTable;
|
|
|
|
static NLS_CountryInfo NLSInfo;
|
|
static CharTable CollateTable;
|
|
|
|
/*-------------------------------------------------------------------------------*/
|
|
|
|
/* einen String anhand einer Tabelle uebersetzen: */
|
|
|
|
static void TranslateString(char *s, CharTable Table)
|
|
BEGIN
|
|
for (; *s!='\0'; s++) *s=Table[((unsigned int) *s)&0xff];
|
|
END
|
|
|
|
/*-------------------------------------------------------------------------------*/
|
|
/* Da es moeglich ist, die aktuelle Codeseite im Programmlauf zu wechseln,
|
|
ist die Initialisierung in einer getrennten Routine untergebracht. Nach
|
|
einem Wechsel stellt ein erneuter Aufruf wieder korrekte Verhaeltnisse
|
|
her. Wen das stoert, der schreibe einfach einen Aufruf in den Initiali-
|
|
sierungsteil der Unit hinein. */
|
|
|
|
#ifdef DOS_NLS
|
|
typedef struct
|
|
{
|
|
Byte TimeFmt;
|
|
Byte DateFmt;
|
|
char Currency[2];
|
|
char ThouSep[2];
|
|
char DecSep[2];
|
|
Byte Reserved[24];
|
|
} Dos2CountryInfo;
|
|
typedef struct
|
|
{
|
|
Word DateFmt;
|
|
char Currency[5];
|
|
char ThouSep[2];
|
|
char DecSep[2];
|
|
char DateSep[2];
|
|
char TimeSep[2];
|
|
Byte CurrFmt;
|
|
Byte CurrDecimals;
|
|
Byte TimeFmt;
|
|
char *UpCasePtr;
|
|
char DataSep[2];
|
|
Byte Dummy[8];
|
|
} Dos3CountryInfo;
|
|
typedef struct
|
|
{
|
|
Byte SubFuncNo;
|
|
char *Result;
|
|
} DosTableRec;
|
|
|
|
char *DosCopy(char *Src, int Len)
|
|
BEGIN
|
|
char *res=malloc(sizeof(char)*(Len+1));
|
|
memcpy(res,Src,Len); res[Len]='\0';
|
|
return res;
|
|
END
|
|
|
|
void StandardUpCases(void)
|
|
BEGIN
|
|
char *s1,*s2;
|
|
|
|
s1=CH_ae; s2=CH_Ae; UpCaseTable[((unsigned int) *s1)&0xff]=*s2;
|
|
s1=CH_oe; s2=CH_Oe; UpCaseTable[((unsigned int) *s1)&0xff]=*s2;
|
|
s1=CH_ue; s2=CH_Ue; UpCaseTable[((unsigned int) *s1)&0xff]=*s2;
|
|
END
|
|
#endif
|
|
|
|
void NLS_Initialize(void)
|
|
BEGIN
|
|
char *tmpstr,*run,*cpy;
|
|
Word FmtBuffer;
|
|
int z;
|
|
#ifdef DEBUG_NLS
|
|
int z2;
|
|
#endif
|
|
Boolean DidDate;
|
|
|
|
#ifdef LOCALE_NLS
|
|
struct lconv *lc;
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
COUNTRYCODE ccode;
|
|
COUNTRYINFO cinfo;
|
|
ULONG erglen;
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
union REGS Regs;
|
|
struct SREGS SRegs;
|
|
void *info;
|
|
Dos2CountryInfo DOS2Info;
|
|
Dos3CountryInfo DOS3Info;
|
|
DosTableRec DOSTablePtr;
|
|
#endif
|
|
|
|
/* get currency format, separators */
|
|
|
|
#ifdef NO_NLS
|
|
NLSInfo.DecSep=".";
|
|
NLSInfo.DataSep=",";
|
|
NLSInfo.ThouSep=",";
|
|
NLSInfo.Currency="$";
|
|
NLSInfo.CurrDecimals=2;
|
|
NLSInfo.CurrFmt=CurrFormatPreNoBlank;
|
|
#endif
|
|
|
|
#ifdef LOCALE_NLS
|
|
lc=localeconv();
|
|
|
|
NLSInfo.DecSep=(lc->mon_decimal_point!=Nil)?lc->decimal_point:".";
|
|
|
|
NLSInfo.ThouSep=(lc->mon_thousands_sep!=Nil)?lc->mon_thousands_sep:",";
|
|
|
|
NLSInfo.DataSep=",";
|
|
|
|
NLSInfo.Currency=(lc->currency_symbol!=Nil)?lc->currency_symbol:"$";
|
|
|
|
NLSInfo.CurrDecimals=lc->int_frac_digits;
|
|
if (NLSInfo.CurrDecimals>4) NLSInfo.CurrDecimals=2;
|
|
|
|
if (lc->p_cs_precedes)
|
|
if (lc->p_sep_by_space) NLSInfo.CurrFmt=CurrFormatPreBlank;
|
|
else NLSInfo.CurrFmt=CurrFormatPreNoBlank;
|
|
else
|
|
if (lc->p_sep_by_space) NLSInfo.CurrFmt=CurrFormatPostBlank;
|
|
else NLSInfo.CurrFmt=CurrFormatPostNoBlank;
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
ccode.country=0; ccode.codepage=0;
|
|
DosQueryCtryInfo(sizeof(cinfo),&ccode,&cinfo,&erglen);
|
|
|
|
NLSInfo.Country=cinfo.country;
|
|
NLSInfo.CodePage=cinfo.codepage;
|
|
NLSInfo.DecSep=strdup(cinfo.szDecimal);
|
|
NLSInfo.DataSep=strdup(cinfo.szDataSeparator);
|
|
NLSInfo.ThouSep=strdup(cinfo.szThousandsSeparator);
|
|
NLSInfo.Currency=strdup(cinfo.szCurrency);
|
|
NLSInfo.CurrDecimals=cinfo.cDecimalPlace;
|
|
NLSInfo.CurrFmt=(CurrFormat) cinfo.fsCurrencyFmt;
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
if (_osmajor<3) NLSInfo.CodePage=437;
|
|
else if (_osminor<30) NLSInfo.CodePage=437;
|
|
else
|
|
BEGIN
|
|
Regs.x.ax=0x6601;
|
|
int86(0x21,&Regs,&Regs);
|
|
NLSInfo.CodePage=Regs.x.bx;
|
|
END
|
|
|
|
Regs.x.ax=0x3800;
|
|
if (_osmajor<3) info=&DOS2Info; else info=&DOS3Info;
|
|
SRegs.ds=FP_SEG(info); Regs.x.dx=FP_OFF(info);
|
|
int86x(0x21,&Regs,&Regs,&SRegs);
|
|
NLSInfo.Country=Regs.x.bx;
|
|
if (_osmajor>=3)
|
|
BEGIN
|
|
NLSInfo.DecSep=DosCopy(DOS3Info.DecSep,2);
|
|
NLSInfo.DataSep=DosCopy(DOS3Info.DataSep,2);
|
|
NLSInfo.ThouSep=DosCopy(DOS3Info.ThouSep,2);
|
|
NLSInfo.Currency=DosCopy(DOS3Info.Currency,5);
|
|
NLSInfo.CurrDecimals=DOS3Info.CurrDecimals;
|
|
NLSInfo.CurrFmt=(CurrFormat) DOS3Info.CurrFmt;
|
|
END
|
|
/* DOS 2 kennt noch nicht soviel, daher muessen wir selber etwas beisteuern */
|
|
else
|
|
BEGIN
|
|
NLSInfo.DecSep=DosCopy(DOS2Info.DecSep,2);
|
|
NLSInfo.DataSep=",";
|
|
NLSInfo.ThouSep=DosCopy(DOS2Info.ThouSep,2);
|
|
NLSInfo.Currency=DosCopy(DOS2Info.Currency,2);
|
|
NLSInfo.CurrDecimals=(NLSInfo.Country==39) ? 0 : 2;
|
|
switch (NLSInfo.Country)
|
|
BEGIN
|
|
case 1: case 39:
|
|
NLSInfo.CurrFmt=CurrFormatPreNoBlank; break;
|
|
case 3: case 33: case 34: case 358:
|
|
NLSInfo.CurrFmt=CurrFormatPostBlank; break;
|
|
default:
|
|
NLSInfo.CurrFmt=CurrFormatPreBlank;
|
|
END
|
|
END
|
|
#endif
|
|
|
|
/* get date format */
|
|
|
|
#ifdef NO_NLS
|
|
tmpstr="%m/%d/%y"; DidDate=False;
|
|
#endif
|
|
|
|
#ifdef LOCALE_NLS
|
|
tmpstr=nl_langinfo(D_FMT);
|
|
if ((tmpstr==Nil) OR (*tmpstr == '\0')) tmpstr="%m/%d/%y";
|
|
DidDate=False;
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
NLSInfo.DateFmt=(DateFormat) cinfo.fsDateFmt;
|
|
NLSInfo.DateSep=strdup(cinfo.szDateSeparator);
|
|
DidDate=True;
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
if (_osmajor>=3)
|
|
BEGIN
|
|
NLSInfo.DateFmt=(DateFormat) DOS3Info.DateFmt;
|
|
NLSInfo.DateSep=DosCopy(DOS3Info.DateSep,2);
|
|
END
|
|
else
|
|
BEGIN
|
|
NLSInfo.DateFmt=(DateFormat) DOS2Info.DateFmt;
|
|
switch (NLSInfo.Country)
|
|
BEGIN
|
|
case 3: case 47: case 351: case 32: case 33: case 39: case 34:
|
|
NLSInfo.DateSep="/"; break;
|
|
case 49: case 358: case 41:
|
|
NLSInfo.DateSep="."; break;
|
|
case 972:
|
|
NLSInfo.DateSep=" "; break;
|
|
default:
|
|
NLSInfo.DateSep="-";
|
|
END
|
|
END
|
|
DidDate=True;
|
|
#endif
|
|
|
|
if (NOT DidDate)
|
|
BEGIN
|
|
NLSInfo.DateSep=Nil; FmtBuffer=0; run=tmpstr;
|
|
while (*run!='\0')
|
|
if (*run=='%')
|
|
BEGIN
|
|
FmtBuffer<<=4;
|
|
switch (toupper(*(++run)))
|
|
BEGIN
|
|
case 'D': FmtBuffer+=1; break;
|
|
case 'M': FmtBuffer+=2; break;
|
|
case 'Y': FmtBuffer+=3; break;
|
|
END
|
|
if (NLSInfo.DateSep==Nil)
|
|
BEGIN
|
|
run++; cpy=NLSInfo.DateSep=strdup(" ");
|
|
while ((*run!=' ') AND (*run!='%')) *(cpy++)=(*(run++));
|
|
*cpy='\0';
|
|
END
|
|
else run++;
|
|
END
|
|
else run++;
|
|
if (FmtBuffer==0x213) NLSInfo.DateFmt=DateFormatMTY;
|
|
else if (FmtBuffer==0x123) NLSInfo.DateFmt=DateFormatTMY;
|
|
else NLSInfo.DateFmt=DateFormatYMT;
|
|
END
|
|
|
|
/* get time format */
|
|
|
|
#ifdef NO_NLS
|
|
tmpstr="%H:%M:%S"; DidDate=False;
|
|
#endif
|
|
|
|
#ifdef LOCALE_NLS
|
|
tmpstr=nl_langinfo(T_FMT);
|
|
if ((tmpstr==Nil) OR (*tmpstr == '\0')) tmpstr="%H:%M:%S";
|
|
DidDate=False;
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
NLSInfo.TimeFmt=(TimeFormat) cinfo.fsTimeFmt;
|
|
NLSInfo.TimeSep=strdup(cinfo.szTimeSeparator);
|
|
DidDate=True;
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
if (_osmajor>=3)
|
|
BEGIN
|
|
NLSInfo.TimeFmt=(TimeFormat) DOS3Info.TimeFmt;
|
|
NLSInfo.TimeSep=DosCopy(DOS3Info.TimeSep,2);
|
|
END
|
|
else
|
|
BEGIN
|
|
NLSInfo.TimeFmt=(TimeFormat) DOS2Info.TimeFmt;
|
|
switch (NLSInfo.Country)
|
|
BEGIN
|
|
case 41: case 46: case 47: case 358:
|
|
NLSInfo.TimeSep=".";
|
|
default:
|
|
NLSInfo.TimeSep=":";
|
|
END
|
|
END
|
|
DidDate=True;
|
|
#endif
|
|
|
|
if (NOT DidDate)
|
|
BEGIN
|
|
NLSInfo.TimeSep=Nil; FmtBuffer=0; run=tmpstr;
|
|
while (*run!='\0')
|
|
if (*run=='%')
|
|
BEGIN
|
|
FmtBuffer<<=4;
|
|
switch (toupper(*(++run)))
|
|
BEGIN
|
|
case 'S': FmtBuffer+=1; break;
|
|
case 'M': FmtBuffer+=2; break;
|
|
case 'H': FmtBuffer+=3; break;
|
|
case 'T': fprintf(stderr, "\nwarning, detected non-ANSI time format specifier '%%T'");
|
|
run = "H:%M:%S"; break;
|
|
case 'R': fprintf(stderr, "\nwarning, detected non-ANSI time format specifier '%%R'");
|
|
run = "H:%M"; break;
|
|
END
|
|
if (NLSInfo.TimeSep==Nil)
|
|
BEGIN
|
|
run++; cpy=NLSInfo.TimeSep=strdup(" ");
|
|
while ((*run != '\0') AND (*run!=' ') AND (*run!='%'))
|
|
*(cpy++)=(*(run++));
|
|
*cpy='\0';
|
|
END
|
|
else run++;
|
|
END
|
|
else run++;
|
|
NLSInfo.TimeFmt=TimeFormatEurope;
|
|
END
|
|
|
|
/* get lower->upper case table */
|
|
|
|
#if defined(NO_NLS) || defined(LOCALE_NLS)
|
|
for (z=0; z<256; z++) UpCaseTable[z]=toupper(z);
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
for (z=0; z<256; z++) UpCaseTable[z]=(char) z;
|
|
for (z='a'; z<='z'; z++) UpCaseTable[z]-='a'-'A';
|
|
DosMapCase(sizeof(UpCaseTable),&ccode,UpCaseTable);
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
for (z=0; z<256; z++) UpCaseTable[z]=(char) z;
|
|
for (z='a'; z<='z'; z++) UpCaseTable[z]-='a'-'A';
|
|
#ifdef __DPMI16__
|
|
StandardUpCases();
|
|
#else
|
|
if ((((Word)_osmajor)*100)+_osminor>=330)
|
|
BEGIN
|
|
Regs.x.ax=0x6502;
|
|
Regs.x.bx=NLSInfo.CodePage;
|
|
Regs.x.dx=NLSInfo.Country;
|
|
Regs.x.cx=sizeof(DOSTablePtr);
|
|
info=&DOSTablePtr; SRegs.es=FP_SEG(info); Regs.x.di=FP_OFF(info);
|
|
int86x(0x21,&Regs,&Regs,&SRegs);
|
|
if (Regs.x.cx==sizeof(DOSTablePtr))
|
|
BEGIN
|
|
DOSTablePtr.Result+=sizeof(Word);
|
|
memcpy(UpCaseTable+128,DOSTablePtr.Result,128);
|
|
END
|
|
else StandardUpCases();
|
|
END
|
|
else StandardUpCases();
|
|
#endif
|
|
#endif
|
|
|
|
/* get upper->lower case table */
|
|
|
|
#if defined(NO_NLS) || defined(LOCALE_NLS)
|
|
for (z=0; z<256; z++) LowCaseTable[z]=tolower(z);
|
|
#endif
|
|
|
|
#if defined(OS2_NLS) || defined(DOS_NLS)
|
|
for (z=0; z<256; z++) LowCaseTable[z]=(char) z;
|
|
for (z=255; z>=0; z--)
|
|
if (UpCaseTable[z]!=(char) z)
|
|
LowCaseTable[((unsigned int) UpCaseTable[z])&0xff]=(char) z;
|
|
#endif
|
|
|
|
/* get collation table */
|
|
|
|
#if defined(NO_NLS) || defined(LOCALE_NLS)
|
|
for (z=0; z<256; z++) CollateTable[z]=z;
|
|
for (z='a'; z<='z'; z++) CollateTable[z]=toupper(z);
|
|
#endif
|
|
|
|
#ifdef OS2_NLS
|
|
for (z=0; z<256; z++) CollateTable[z]=(char) z;
|
|
DosQueryCollate(sizeof(CollateTable),&ccode,CollateTable,&erglen);
|
|
#endif
|
|
|
|
#ifdef DOS_NLS
|
|
for (z=0; z<256; z++) CollateTable[z]=(char) z;
|
|
for (z='a'; z<='z'; z++) CollateTable[z]=(char) (z-('a'-'A'));
|
|
#ifndef __DPMI16__
|
|
if ((((Word)_osmajor)*100)+_osminor>=330)
|
|
BEGIN
|
|
Regs.x.ax=0x6506;
|
|
Regs.x.bx=NLSInfo.CodePage;
|
|
Regs.x.dx=NLSInfo.Country;
|
|
Regs.x.cx=sizeof(DOSTablePtr);
|
|
info=&DOSTablePtr; SRegs.es=FP_SEG(info); Regs.x.di=FP_OFF(info);
|
|
int86x(0x21,&Regs,&Regs,&SRegs);
|
|
if (Regs.x.cx==sizeof(DOSTablePtr))
|
|
BEGIN
|
|
DOSTablePtr.Result+=sizeof(Word);
|
|
memcpy(CollateTable,DOSTablePtr.Result,256);
|
|
END
|
|
END
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef DEBUG_NLS
|
|
printf("Country = %d\n",NLSInfo.Country);
|
|
printf("CodePage = %d\n",NLSInfo.CodePage);
|
|
printf("DateFmt = ");
|
|
switch(NLSInfo.DateFmt)
|
|
BEGIN
|
|
case DateFormatMTY: printf("MTY\n"); break;
|
|
case DateFormatTMY: printf("TMY\n"); break;
|
|
case DateFormatYMT: printf("YMT\n"); break;
|
|
default: printf("???\n");
|
|
END
|
|
printf("DateSep = %s\n",NLSInfo.DateSep);
|
|
printf("TimeFmt = ");
|
|
switch(NLSInfo.TimeFmt)
|
|
BEGIN
|
|
case TimeFormatUSA: printf("USA\n"); break;
|
|
case TimeFormatEurope: printf("Europe\n"); break;
|
|
case TimeFormatJapan: printf("Japan\n"); break;
|
|
default: printf("???\n");
|
|
END
|
|
printf("TimeSep = %s\n",NLSInfo.TimeSep);
|
|
printf("Currency = %s\n",NLSInfo.Currency);
|
|
printf("CurrFmt = ");
|
|
switch (NLSInfo.CurrFmt)
|
|
BEGIN
|
|
case CurrFormatPreNoBlank: printf("PreNoBlank\n"); break;
|
|
case CurrFormatPostNoBlank: printf("PostNoBlank\n"); break;
|
|
case CurrFormatPreBlank: printf("PreBlank\n"); break;
|
|
case CurrFormatPostBlank: printf("PostBlank\n"); break;
|
|
default: printf("???\n");
|
|
END
|
|
printf("CurrDecimals = %d\n",NLSInfo.CurrDecimals);
|
|
printf("ThouSep = %s\n",NLSInfo.ThouSep);
|
|
printf("DecSep = %s\n",NLSInfo.DecSep);
|
|
printf("DataSep = %s\n",NLSInfo.DataSep);
|
|
|
|
printf("\nUpcaseTable:\n");
|
|
for (z=0; z<4; z++)
|
|
BEGIN
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(z*64+z2); putchar ('\n');
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(UpCaseTable[z*64+z2]); putchar ('\n');
|
|
putchar('\n');
|
|
END
|
|
|
|
printf("\nLowcaseTable:\n");
|
|
for (z=0; z<4; z++)
|
|
BEGIN
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(z*64+z2); putchar ('\n');
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(LowCaseTable[z*64+z2]); putchar ('\n');
|
|
putchar('\n');
|
|
END
|
|
|
|
printf("\nCollateTable:\n");
|
|
for (z=0; z<4; z++)
|
|
BEGIN
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(z*64+z2); putchar ('\n');
|
|
for (z2=0; z2<63; z2++) if (z*64+z2>32) putchar(CollateTable[z*64+z2]); putchar ('\n');
|
|
putchar('\n');
|
|
END
|
|
|
|
exit(0);
|
|
#endif
|
|
END
|
|
|
|
void NLS_GetCountryInfo(NLS_CountryInfo *Info)
|
|
BEGIN
|
|
*Info=NLSInfo;
|
|
END
|
|
|
|
void NLS_DateString(Word Year, Word Month, Word Day, char *Dest)
|
|
BEGIN
|
|
switch (NLSInfo.DateFmt)
|
|
BEGIN
|
|
case DateFormatMTY:
|
|
sprintf(Dest,"%d%s%d%s%d",Month,NLSInfo.DateSep,Day,NLSInfo.DateSep,Year); break;
|
|
case DateFormatTMY:
|
|
sprintf(Dest,"%d%s%d%s%d",Day,NLSInfo.DateSep,Month,NLSInfo.DateSep,Year); break;
|
|
case DateFormatYMT:
|
|
sprintf(Dest,"%d%s%d%s%d",Year,NLSInfo.DateSep,Month,NLSInfo.DateSep,Day); break;
|
|
END
|
|
END
|
|
|
|
void NLS_CurrDateString(char *Dest)
|
|
BEGIN
|
|
time_t timep;
|
|
struct tm *trec;
|
|
|
|
time(&timep); trec=localtime(&timep);
|
|
NLS_DateString(trec->tm_year+1900,trec->tm_mon+1,trec->tm_mday,Dest);
|
|
END
|
|
|
|
void NLS_TimeString(Word Hour, Word Minute, Word Second, Word Sec100, char *Dest)
|
|
BEGIN
|
|
Word OriHour;
|
|
String ext;
|
|
|
|
OriHour=Hour;
|
|
if (NLSInfo.TimeFmt==TimeFormatUSA)
|
|
BEGIN
|
|
Hour%=12; if (Hour==0) Hour=12;
|
|
END
|
|
sprintf(Dest,"%d%s%02d%s%02d",Hour,NLSInfo.TimeSep,Minute,NLSInfo.TimeSep,Second);
|
|
if (Sec100<100)
|
|
BEGIN
|
|
sprintf(ext,"%s%02d",NLSInfo.DecSep,Sec100); strcat(Dest,ext);
|
|
END
|
|
if (NLSInfo.TimeFmt==TimeFormatUSA)
|
|
strcat(Dest,(OriHour>12)?"p":"a");
|
|
END
|
|
|
|
void NLS_CurrTimeString(Boolean Use100, char *Dest)
|
|
BEGIN
|
|
time_t timep;
|
|
struct tm *trec;
|
|
|
|
time(&timep); trec=localtime(&timep);
|
|
NLS_TimeString(trec->tm_hour,trec->tm_min,trec->tm_sec,Use100?0:100,Dest);
|
|
END
|
|
|
|
void NLS_CurrencyString(double inp, char *erg)
|
|
BEGIN
|
|
char s[1024],form[1024];
|
|
char *p,*z;
|
|
|
|
/* Schritt 1: mit passender Nachkommastellenzahl wandeln */
|
|
|
|
sprintf(form,"%%0.%df",NLSInfo.CurrDecimals);
|
|
sprintf(s,form,inp);
|
|
|
|
/* Schritt 2: vorne den Punkt suchen */
|
|
|
|
p=(NLSInfo.CurrDecimals==0) ? s+strlen(s) : strchr(s,'.');
|
|
|
|
/* Schritt 3: Tausenderstellen einfuegen */
|
|
|
|
z=p;
|
|
while (z-s>3)
|
|
BEGIN
|
|
strins(s,NLSInfo.ThouSep,z-s-3); z-=3; p+=strlen(NLSInfo.ThouSep);
|
|
END;
|
|
|
|
/* Schritt 4: Komma anpassen */
|
|
|
|
strcpy(p,p+1); strins(s,NLSInfo.DecSep,p-s);
|
|
|
|
/* Schritt 5: Einheit anbauen */
|
|
|
|
switch (NLSInfo.CurrFmt)
|
|
BEGIN
|
|
case CurrFormatPreNoBlank:
|
|
sprintf(erg,"%s%s",NLSInfo.Currency,s); break;
|
|
case CurrFormatPreBlank:
|
|
sprintf(erg,"%s %s",NLSInfo.Currency,s); break;
|
|
case CurrFormatPostNoBlank:
|
|
sprintf(erg,"%s%s",s,NLSInfo.Currency); break;
|
|
case CurrFormatPostBlank:
|
|
sprintf(erg,"%s%s",s,NLSInfo.Currency); break;
|
|
default:
|
|
strcpy(p,p+strlen(NLSInfo.DecSep)); strins(NLSInfo.Currency,s,p-s);
|
|
END
|
|
END
|
|
|
|
char Upcase(char inp)
|
|
BEGIN
|
|
return UpCaseTable[((unsigned int) inp)&0xff];
|
|
END
|
|
|
|
void NLS_UpString(char *s)
|
|
BEGIN
|
|
char *z;
|
|
|
|
for (z=s; *z!='\0'; z++) *z=UpCaseTable[((unsigned int)*z)&0xff];
|
|
END
|
|
|
|
void NLS_LowString(char *s)
|
|
BEGIN
|
|
char *z;
|
|
|
|
for (z=s; *z!='\0'; z++) *z=LowCaseTable[((unsigned int)*z)&0xff];
|
|
END
|
|
|
|
int NLS_StrCmp(const char *s1, const char *s2)
|
|
BEGIN
|
|
while (CollateTable[((unsigned int)*s1)&0xff]==CollateTable[((unsigned int)*s2)&0xff])
|
|
BEGIN
|
|
if ((NOT *s1) AND (NOT *s2)) return 0;
|
|
s1++; s2++;
|
|
END
|
|
return ((int) CollateTable[((unsigned int)*s1)&0xff]-CollateTable[((unsigned int)*s2)&0xff]);
|
|
END
|
|
|
|
void nls_init(void)
|
|
BEGIN
|
|
#ifdef LOCALE_NLS
|
|
(void) setlocale(LC_TIME,"");
|
|
(void) setlocale(LC_MONETARY,"");
|
|
#endif
|
|
END
|