Subversion Repositories SvarDOS

Compare Revisions

Ignore whitespace Rev 590 → Rev 591

/localcfg/trunk/country.c
1,6 → 1,6
/*
* functions that read/write from/to the localcfg country.sys-like file.
* Copyright (C) Mateusz Viste 2015
* functions that reads/writes from/to the localcfg country.sys-like file.
* Copyright (C) Mateusz Viste 2015-2022
*/
 
#include <stdio.h>
9,36 → 9,43
#include "country.h"
 
 
#define READSHORT(x) (short)(x[0] | (x[1] << 8))
struct funchdr {
unsigned char funcname[8];
unsigned short funcsiz;
};
 
 
/* fills a country struct with default values */
static void country_default(struct country *countrydata) {
/* first clears the memory */
memset(countrydata, 0, sizeof(struct country));
/* fill in fields - only non-zero values */
countrydata->id = 1;
countrydata->codepage = 437;
/* countrydata->datefmt = COUNTRY_DATE_MDY;
countrydata->timefmt = COUNTRY_TIME12; */
countrydata->currency[0] = '$';
countrydata->decimal = '.';
countrydata->thousands = ',';
countrydata->datesep = '/';
countrydata->timesep = ':';
countrydata->currencyprec = 2;
/* countrydata->currencydecsym = 0; */
/* countrydata->currencyspace = 0; */
/* countrydata->currencypos = 0; */
countrydata->yes = 'Y';
countrydata->no = 'N';
 
/* first clear the memory */
bzero(countrydata, sizeof(struct country));
 
/* fill in CTYINFO fields (non-zero values only) */
countrydata->CTYINFO.id = 1;
countrydata->CTYINFO.codepage = 437;
/* countrydata->CTYINFO.datefmt = COUNTRY_DATE_MDY;
countrydata->CTYINFO.timefmt = COUNTRY_TIME12; */
countrydata->CTYINFO.currsym[0] = '$';
countrydata->CTYINFO.decimal[0] = '.';
countrydata->CTYINFO.thousands[0] = ',';
countrydata->CTYINFO.datesep[0] = '/';
countrydata->CTYINFO.timesep[0] = ':';
countrydata->CTYINFO.currprec = 2;
/* countrydata->CTYINFO.currencydecsym = 0; */
/* countrydata->CTYINFO.currencyspace = 0; */
/* countrydata->CTYINFO.currencypos = 0; */
 
/* fill in YESNO fields (non-zero values only) */
countrydata->YESNO.yes[0] = 'Y';
countrydata->YESNO.no[0] = 'N';
}
 
 
/* Loads data from a country.sys file into a country struct.
* Returns 0 on success, non-zero otherwise. */
int country_read(struct country *countrydata, char *fname) {
int country_read(struct country *countrydata, const char *fname) {
unsigned char filebuff[1024];
unsigned char buff[64];
short firstentryoffs;
unsigned char *subfunctions[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
58,22 → 65,19
fclose(fd);
 
/* check that it's a country file - should start with 0xFF COUNTRY 0x00 */
if (filebuff[0] != 0xFF) return(-2);
if (strcmp((char *)filebuff + 1, "COUNTRY") != 0) return(-2);
if (memcmp(filebuff, "\377COUNTRY\0", 9) != 0) return(-2);
 
/* check that it's one of my country.sys files - should contain a trailer */
memcpy(buff, filebuff + filesize - 8, 8);
buff[8] = 0;
if (strcmp((char *)buff, "LOCALCFG") != 0) return(-3);
if (memcmp(filebuff + filesize - 8, "LOCALCFG", 8) != 0) return(-3);
 
/* read the offset of the entries index - must be at least 23 */
functiondata = filebuff + 19;
firstentryoffs = READSHORT(functiondata);
firstentryoffs = *((unsigned short *)functiondata);
if ((firstentryoffs < 23) || (firstentryoffs >= filesize)) return(-4);
functiondata = filebuff + firstentryoffs;
 
/* how many entries do we have? I expect exactly one. */
if (READSHORT(functiondata) != 1) return(-5);
if (*((unsigned short *)functiondata) != 1) return(-5);
/* skip to the first country entry */
functiondata += 2;
 
86,18 → 90,18
/* printf("Codepage = %d\n", READSHORT(functiondata)); */
functiondata += 2; /* skip codepage */
functiondata += 4; /* skip reserved fields */
firstentryoffs = READSHORT(functiondata); /* read offset of the subfunctions index */
firstentryoffs = *((unsigned short *)functiondata); /* read offset of the subfunctions index */
functiondata = filebuff + firstentryoffs;
 
/* read all subfunctions, but no more than 15 */
subfunctionscount = READSHORT(functiondata);
subfunctionscount = *((unsigned short *)functiondata);
/* printf("Found %d subfunctions\n", subfunctionscount); */
functiondata += 2;
for (x = 0; (x < 15) && (x < subfunctionscount); x++) {
short size = READSHORT(functiondata);
short size = *((unsigned short *)functiondata);
functiondata += 2;
functiondata += 2; /* skip ID of the subfunction */
subfunctions[x] = filebuff + READSHORT(functiondata);
subfunctions[x] = filebuff + *((unsigned short *)functiondata);
/* printf("subfunction %d at 0x%p\n", x, subfunctions[x]); */
functiondata += size - 2;
}
104,58 → 108,13
 
/* load every subfunction, and feed the country struct with data */
for (x = 0; subfunctions[x] != NULL; x++) {
short functionsize;
/* the function name should always start with 0xFF */
if (subfunctions[x][0] != 0xFF) return(-6);
/* load the subfunction's name, and act accordingly */
memcpy(buff, subfunctions[x] + 1, 7);
buff[7] = 0;
functiondata = subfunctions[x] + 8;
functionsize = READSHORT(functiondata);
struct funchdr *hdr = (void *)(subfunctions[x]);
functiondata = subfunctions[x] + 10;
/* */
if (strcmp((char *)buff, "YESNO ") == 0) {
if (functionsize != 4) continue;
countrydata->yes = functiondata[0];
countrydata->no = functiondata[2];
} else if (strcmp((char *)buff, "CTYINFO") == 0) {
if (functionsize != 22) continue;
/* ID */
countrydata->id = READSHORT(functiondata);
functiondata += 2;
/* codepage */
countrydata->codepage = READSHORT(functiondata);
functiondata += 2;
/* date format */
countrydata->datefmt = READSHORT(functiondata);
functiondata += 2;
/* currency symbol */
countrydata->currency[0] = functiondata[0];
countrydata->currency[1] = functiondata[1];
countrydata->currency[2] = functiondata[2];
countrydata->currency[3] = functiondata[3];
countrydata->currency[4] = 0;
functiondata += 5;
/* thousands separator, decimal sep, date sep, time sep */
countrydata->thousands = READSHORT(functiondata);
functiondata += 2;
countrydata->decimal = READSHORT(functiondata);
functiondata += 2;
countrydata->datesep = READSHORT(functiondata);
functiondata += 2;
countrydata->timesep = READSHORT(functiondata);
functiondata += 2;
/* currency format */
countrydata->currencypos = *functiondata & 1;
countrydata->currencyspace = (*functiondata >> 1) & 1;
countrydata->currencydecsym = (*functiondata >> 2) & 1;
functiondata += 1;
/* currency precision */
countrydata->currencyprec = *functiondata;
functiondata += 1;
/* time format */
countrydata->timefmt = *functiondata;
functiondata += 1;
if ((memcmp(hdr->funcname, "\377YESNO ", 8) == 0) && (hdr->funcsiz == 4)) {
memcpy(&(countrydata->YESNO), functiondata, hdr->funcsiz);
} else if ((memcmp(hdr->funcname, "\377CTYINFO", 8) == 0) && (hdr->funcsiz == 22)) {
memcpy(&(countrydata->CTYINFO), functiondata, hdr->funcsiz);
}
}
 
166,15 → 125,10
#define MSB(x) (((x) >> 8) & 0xff)
#define LSB(x) ((x) & 0xff)
 
#define DWORDB1(x) ((x) & 0xff)
#define DWORDB2(x) (((x) >> 8) & 0xff)
#define DWORDB3(x) (((x) >> 16) & 0xff)
#define DWORDB4(x) (((x) >> 24) & 0xff)
 
 
/* Computes a new country.sys file based on data from a country struct.
* Returns 0 on success, non-zero otherwise. */
int country_write(char *fname, struct country *c) {
int country_write(const char *fname, struct country *c) {
unsigned char filebuff[1024];
short filesize = 0;
FILE *fd;
232,41 → 186,37
240, 241, 242, 243, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255};
 
/* zero out filebuff */
bzero(filebuff, sizeof(filebuff));
 
/* compute the country.sys structures */
memcpy(filebuff, "\377COUNTRY\0\0\0\0\0\0\0\0\1\0\1", 19); /* header */
filesize = 19;
/* first entry offset (always current offset+4) */
filebuff[filesize + 0] = DWORDB1(filesize+4);
filebuff[filesize + 1] = DWORDB2(filesize+4);
filebuff[filesize + 2] = DWORDB3(filesize+4);
filebuff[filesize + 3] = DWORDB4(filesize+4);
filesize += 4;
memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
/* number of entries */
filebuff[filesize++] = 1;
filebuff[filesize++] = 0;
filebuff[filesize] = 1;
filesize += 2;
/* first (and only) entry / size, country, codepage, reserved(2), offset */
filebuff[filesize++] = 12; /* size LSB */
filebuff[filesize++] = 0; /* size MSB */
filebuff[filesize++] = LSB(c->id); /* country LSB */
filebuff[filesize++] = MSB(c->id); /* country MSB */
filebuff[filesize++] = LSB(c->codepage); /* codepage LSB */
filebuff[filesize++] = MSB(c->codepage); /* codepage MSB */
filebuff[filesize++] = 0; /* reserved */
filebuff[filesize++] = 0; /* reserved */
filebuff[filesize++] = 0; /* reserved */
filebuff[filesize++] = 0; /* reserved */
filebuff[filesize + 0] = DWORDB1(filesize+4); /* offset for subfunctions list (ptr + 4) */
filebuff[filesize + 1] = DWORDB2(filesize+4); /* offset for subfunctions list (ptr + 4) */
filebuff[filesize + 2] = DWORDB3(filesize+4); /* offset for subfunctions list (ptr + 4) */
filebuff[filesize + 3] = DWORDB4(filesize+4); /* offset for subfunctions list (ptr + 4) */
filebuff[filesize++] = LSB(c->CTYINFO.id); /* country LSB */
filebuff[filesize++] = MSB(c->CTYINFO.id); /* country MSB */
filebuff[filesize++] = LSB(c->CTYINFO.codepage); /* codepage LSB */
filebuff[filesize++] = MSB(c->CTYINFO.codepage); /* codepage MSB */
filesize += 4; /* reserved bytes */
 
filesize += 4;
memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
 
/* index of subfunctions */
filebuff[filesize++] = 7; /* there are 7 subfunctions */
filebuff[filesize++] = 0;
filebuff[filesize] = 7; /* there are 7 subfunctions */
filesize += 2;
for (x = 0; x < 7; x++) { /* dump each subfunction (size, id, offset) */
/* size is always 6 */
filebuff[filesize++] = 6;
filebuff[filesize++] = 0;
filebuff[filesize] = 6;
filesize += 2;
/* id of the subfunction */
filebuff[filesize++] = LSB(subfunction_id[x]);
filebuff[filesize++] = MSB(subfunction_id[x]);
274,52 → 224,25
subfunction_ptr[x] = filesize;
filesize += 4;
}
 
/* write the CTYINFO subfunction */
filebuff[subfunction_ptr[0]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[0]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[0]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[0]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[0], &filesize, sizeof(filesize));
 
/* subfunction header */
memcpy(filebuff + filesize, "\377CTYINFO", 8);
filesize += 8;
/* subfunction size */
filebuff[filesize++] = 22;
filebuff[filesize++] = 0;
filebuff[filesize] = 22;
filesize += 2;
 
/* country preferences */
filebuff[filesize++] = LSB(c->id); /* ID */
filebuff[filesize++] = MSB(c->id); /* ID */
filebuff[filesize++] = LSB(c->codepage); /* CP */
filebuff[filesize++] = MSB(c->codepage); /* CP */
filebuff[filesize++] = LSB(c->datefmt); /* date format */
filebuff[filesize++] = MSB(c->datefmt); /* date format */
for (x = 0; x < 5; x++) {
filebuff[filesize++] = c->currency[x]; /* currency */
}
filebuff[filesize++] = LSB(c->thousands); /* thousands separator LSB */
filebuff[filesize++] = MSB(c->thousands); /* thousands separator MSB */
filebuff[filesize++] = LSB(c->decimal); /* decimal separator LSB */
filebuff[filesize++] = MSB(c->decimal); /* decimal separator MSB */
filebuff[filesize++] = LSB(c->datesep); /* date separator LSB */
filebuff[filesize++] = MSB(c->datesep); /* date separator MSB */
filebuff[filesize++] = LSB(c->timesep); /* time separator LSB */
filebuff[filesize++] = MSB(c->timesep); /* time separator MSB */
filebuff[filesize] = c->currencydecsym; /* currency format (bit 2) */
filebuff[filesize] <<= 8;
filebuff[filesize] |= c->currencyspace; /* currency format (bit 1) */
filebuff[filesize] <<= 8;
filebuff[filesize++] |= c->currencypos; /* currency format (bit 0) */
filebuff[filesize++] = c->currencyprec; /* currency precision */
filebuff[filesize++] = c->timefmt; /* time format */
memcpy(filebuff + filesize, &(c->CTYINFO), 22);
filesize += 22;
 
/* write the UCASE subfunction (used for LCASE, too) */
filebuff[subfunction_ptr[1]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[1]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[1]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[1]+3] = DWORDB4(filesize); /* correct value */
filebuff[subfunction_ptr[2]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[2]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[2]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[2]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[1], &filesize, sizeof(filesize));
memcpy(filebuff + subfunction_ptr[2], &filesize, sizeof(filesize));
 
/* subfunction header */
memcpy(filebuff + filesize, "\377UCASE ", 8);
filesize += 8;
327,15 → 250,12
filebuff[filesize++] = 128;
filebuff[filesize++] = 0;
/* UCASE table */
for (x = 0; x < 128; x++) {
filebuff[filesize++] = ucase_437[x];
}
memcpy(filebuff + filesize, ucase_437, 128);
filesize += 128;
 
/* write the FCHAR subfunction (filename terminator table) */
filebuff[subfunction_ptr[3]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[3]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[3]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[3]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[3], &filesize, sizeof(filesize));
 
/* subfunction header */
memcpy(filebuff + filesize, "\377FCHAR ", 8);
filesize += 8;
368,10 → 288,8
filebuff[filesize++] = 44; /* , */
 
/* write the COLLATE subfunction */
filebuff[subfunction_ptr[4]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[4]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[4]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[4]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[4], &filesize, sizeof(filesize));
 
/* subfunction header */
memcpy(filebuff + filesize, "\377COLLATE", 8);
filesize += 8;
379,15 → 297,11
filebuff[filesize++] = LSB(256);
filebuff[filesize++] = MSB(256);
/* collation for standard CP437 */
for (x = 0; x < 256; x++) {
filebuff[filesize++] = collate_437[x];
}
memcpy(filebuff + filesize, collate_437, 256);
filesize += 256;
 
/* write the DBCS subfunction */
filebuff[subfunction_ptr[5]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[5]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[5]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[5]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[5], &filesize, sizeof(filesize));
/* subfunction header */
memcpy(filebuff + filesize, "\377DBCS ", 8);
filesize += 8;
399,18 → 313,13
filebuff[filesize++] = 0;
 
/* write the YESNO subfunction */
filebuff[subfunction_ptr[6]+0] = DWORDB1(filesize); /* update the */
filebuff[subfunction_ptr[6]+1] = DWORDB2(filesize); /* subfunction */
filebuff[subfunction_ptr[6]+2] = DWORDB3(filesize); /* pointer with */
filebuff[subfunction_ptr[6]+3] = DWORDB4(filesize); /* correct value */
memcpy(filebuff + subfunction_ptr[6], &filesize, sizeof(filesize));
memcpy(filebuff + filesize, "\377YESNO ", 8);
filesize += 8;
filebuff[filesize++] = 4; /* size (LSB) */
filebuff[filesize++] = 0; /* size (MSB) */
filebuff[filesize++] = c->yes; /* "Yes" letter */
filebuff[filesize++] = 0;
filebuff[filesize++] = c->no; /* "No" letter */
filebuff[filesize++] = 0;
filebuff[filesize] = 4; /* size (LSB) */
filesize += 2;
memcpy(filebuff + filesize, &(c->YESNO), 4);
filesize += 4;
 
/* write the file trailer */
memcpy(filebuff + filesize, "LOCALCFG", 8);
/localcfg/trunk/country.h
1,6 → 1,6
/*
* functions that read/write from/to the localcfg country.sys-like file.
* Copyright (C) Mateusz Viste 2015
* Copyright (C) Mateusz Viste 2015-2022
*/
 
#ifndef country_h_sentinel
18,30 → 18,39
};
 
 
 
struct country {
char currency[5]; /* currency symbold, ASCIIZ, 4 letters max */
enum COUNTRY_DATEFMT datefmt; /* date format */
enum COUNTRY_TIMEFMT timefmt; /* time format */
short id; /* international ID */
short codepage; /* usual codepage */
unsigned char currencyprec; /* currency precision (2 = 0.12) */
unsigned char currencydecsym; /* set if the currency symbol should replace the decimal point */
unsigned char currencyspace; /* set if the currency symbol should be one space away from the value */
unsigned char currencypos; /* 0=currency symbol precedes the value, 1=follows it */
char decimal; /* decimal separator (like . or ,) */
char thousands; /* thousands separatot */
char datesep; /* date separator (usually '-', '.' or '/') */
char timesep; /* time separator (usually ':') */
char yes; /* the "yes" character (example: 'Y') */
char no; /* the "no" character (example: 'N') */
 
struct {
unsigned short id; /* international id (48=PL, 33=FR, 01=US...) */
unsigned short codepage; /* usual codepage */
unsigned short datefmt; /* date format */
char currsym[5]; /* currency symbol */
char thousands[2]; /* thousands separator */
char decimal[2]; /* decimal separator (like . or ,) */
char datesep[2]; /* date separator (usually '-', '.' or '/') */
char timesep[2]; /* time separator (usually ':') */
unsigned char currpos:1; /* 0=currency precedes the value, 1=follows it */
unsigned char currspace:1; /* set if the currency symbol should be one space away from the value */
unsigned char currdecsym:1; /* set if the currency symbol should replace the decimal point */
unsigned char ZEROED:5;
unsigned char currprec; /* currency precision (2 = 0.12) */
unsigned char timefmt; /* time format */
} CTYINFO;
 
struct {
char yes[2];
char no[2];
} YESNO;
 
};
 
/* Loads data from a country.sys file into a country struct.
* Returns 0 on success, non-zero otherwise. */
int country_read(struct country *countrydata, char *fname);
int country_read(struct country *countrydata, const char *fname);
 
/* Computes a new country.sys file based on data from a country struct.
* Returns 0 on success, non-zero otherwise. */
int country_write(char *fname, struct country *countrydata);
int country_write(const char *fname, struct country *countrydata);
 
#endif
/localcfg/trunk/history.txt
1,7 → 1,8
localcfg history file
 
* localcfg xxxx (merged into the SvarDOS project)
* localcfg ver 20220202 (merged into the SvarDOS project)
- COUNTRY=xxx example contains the actual codepage and path to COUNTRY.SYS
- improved loading/saving routines so they rely on memory structures
 
* localcfg v0.90 [02 June 2015]
- first public release
/localcfg/trunk/localcfg.c
19,13 → 19,13
 
#include "country.h"
 
#define PVER "0.90"
#define PVER "20220202"
#define PDATE "2015-2022"
 
 
static void about(void) {
puts("localcfg v" PVER " - locales configuration for DOS\n"
"Copyright (C) Mateusz Viste 2015 / http://localcfg.sourceforge.net\n"
puts("localcfg ver " PVER " - locales configuration for DOS\n"
"Copyright (C) Mateusz Viste " PDATE "\n"
"\n"
"localcfg creates a custom COUNTRY.SYS-like file matching your preferences.\n"
"\n"
53,16 → 53,16
 
static char *datestring(struct country *c) {
static char result[16];
switch (c->datefmt) {
switch (c->CTYINFO.datefmt) {
case COUNTRY_DATE_MDY:
sprintf(result, "12%c31%c1990", c->datesep, c->datesep);
sprintf(result, "12%c31%c1990", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
break;
case COUNTRY_DATE_DMY:
sprintf(result, "31%c12%c1990", c->datesep, c->datesep);
sprintf(result, "31%c12%c1990", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
break;
case COUNTRY_DATE_YMD:
default:
sprintf(result, "1990%c12%c31", c->datesep, c->datesep);
sprintf(result, "1990%c12%c31", c->CTYINFO.datesep[0], c->CTYINFO.datesep[0]);
break;
}
return(result);
71,10 → 71,10
 
static char *timestring(struct country *c) {
static char result[16];
if (c->timefmt == COUNTRY_TIME12) {
sprintf(result, "11%c59%c59 PM", c->timesep, c->timesep);
if (c->CTYINFO.timefmt == COUNTRY_TIME12) {
sprintf(result, "11%c59%c59 PM", c->CTYINFO.timesep[0], c->CTYINFO.timesep[0]);
} else {
sprintf(result, "23%c59%c59", c->timesep, c->timesep);
sprintf(result, "23%c59%c59", c->CTYINFO.timesep[0], c->CTYINFO.timesep[0]);
}
return(result);
}
97,24 → 97,24
decimalpart[8] = '9';
decimalpart[9] = 0;
/* prepare the decimal string first */
if (c->currencyprec < 9) {
decimalpart[c->currencyprec] = 0;
if (c->CTYINFO.currprec < 9) {
decimalpart[c->CTYINFO.currprec] = 0;
}
/* prepare the currency space string */
if (c->currencyspace != 0) {
if (c->CTYINFO.currspace != 0) {
space[0] = ' ';
}
/* prepare the currency and decimal symbols */
if (c->currencydecsym != 0) { /* currency replaces the decimal point */
sprintf(decsym, "%s", c->currency);
if (c->CTYINFO.currdecsym != 0) { /* currency replaces the decimal point */
sprintf(decsym, "%s", c->CTYINFO.currsym);
cursym[0] = 0;
} else {
sprintf(decsym, "%c", c->decimal);
sprintf(cursym, "%s", c->currency);
sprintf(decsym, "%c", c->CTYINFO.decimal[0]);
sprintf(cursym, "%s", c->CTYINFO.currsym);
}
if (c->currencyprec == 0) decsym[0] = 0;
if (c->CTYINFO.currprec == 0) decsym[0] = 0;
/* compute the final string */
if (c->currencypos == 0) { /* currency precedes value */
if (c->CTYINFO.currpos == 0) { /* currency precedes value */
sprintf(result, "%s%s99%s%s", cursym, space, decsym, decimalpart);
} else { /* currency follows value or replaces decimal symbol */
sprintf(result, "99%s%s%s%s", decsym, decimalpart, space, cursym);
154,69 → 154,69
if (stringstartswith(arg, "country:") == 0) {
intvalue = atoi(value);
if ((intvalue > 0) && (intvalue < 1000)) {
c->id = intvalue;
c->CTYINFO.id = intvalue;
return(0);
}
} else if (stringstartswith(arg, "cp:") == 0) {
intvalue = atoi(value);
if ((intvalue > 0) && (intvalue < 1000)) {
c->codepage = intvalue;
c->CTYINFO.codepage = intvalue;
return(0);
}
} else if (stringstartswith(arg, "decim:") == 0) {
if (value[1] == 0) { /* value must be exactly one character */
c->decimal = *value;
c->CTYINFO.decimal[0] = *value;
return(0);
}
} else if (stringstartswith(arg, "thous:") == 0) {
if (value[1] == 0) { /* value must be exactly one character */
c->thousands = *value;
c->CTYINFO.thousands[0] = *value;
return(0);
}
} else if (stringstartswith(arg, "datesep:") == 0) {
if (value[1] == 0) { /* value must be exactly one character */
c->datesep = *value;
c->CTYINFO.datesep[0] = *value;
return(0);
}
} else if (stringstartswith(arg, "timesep:") == 0) {
if (value[1] == 0) { /* value must be exactly one character */
c->timesep = *value;
c->CTYINFO.timesep[0] = *value;
return(0);
}
} else if (stringstartswith(arg, "datefmt:") == 0) {
if (strcmp(value, "MDY") == 0) {
c->datefmt = COUNTRY_DATE_MDY;
c->CTYINFO.datefmt = COUNTRY_DATE_MDY;
return(0);
} else if (strcmp(value, "DMY") == 0) {
c->datefmt = COUNTRY_DATE_DMY;
c->CTYINFO.datefmt = COUNTRY_DATE_DMY;
return(0);
} else if (strcmp(value, "YMD") == 0) {
c->datefmt = COUNTRY_DATE_YMD;
c->CTYINFO.datefmt = COUNTRY_DATE_YMD;
return(0);
}
} else if (stringstartswith(arg, "timefmt:") == 0) {
if (value[1] == 0) {
if ((value[0] >= '0') && (value[0] <= '1')) {
c->timefmt = value[0] - '0';
c->CTYINFO.timefmt = value[0] - '0';
return(0);
}
}
} else if (stringstartswith(arg, "curr:") == 0) {
if (strlen(value) <= 4) {
strcpy(c->currency, value);
strcpy(c->CTYINFO.currsym, value);
return(0);
}
} else if (stringstartswith(arg, "currpos:") == 0) {
if (value[1] == 0) {
if (value[0] == '0') {
c->currencypos = 0;
c->CTYINFO.currpos = 0;
return(0);
} else if (value[0] == '1') {
c->currencypos = 1;
c->CTYINFO.currpos = 1;
return(0);
} else if (value[0] == '2') {
c->currencypos = 0;
c->currencydecsym = 1;
c->CTYINFO.currpos = 0;
c->CTYINFO.currdecsym = 1;
return(0);
}
}
223,7 → 223,7
} else if (stringstartswith(arg, "currspc:") == 0) {
if (value[1] == 0) {
if ((value[0] >= '0') && (value[0] <= '1')) {
c->currencyspace = value[0] - '0';
c->CTYINFO.currspace = value[0] - '0';
return(0);
}
}
230,7 → 230,7
} else if (stringstartswith(arg, "currprec:") == 0) {
if (value[1] == 0) {
if ((value[0] >= '0') && (value[0] <= '9')) {
c->currencyprec = value[0] - '0';
c->CTYINFO.currprec = value[0] - '0';
return(0);
}
}
237,8 → 237,8
} else if (stringstartswith(arg, "yesno:") == 0) {
/* string must be exactly 2 characters long */
if ((value[0] != 0) && (value[1] != 0) && (value[2] == 0)) {
c->yes = value[0];
c->no = value[1];
c->YESNO.yes[0] = value[0];
c->YESNO.no[0] = value[1];
return(0);
}
}
300,19 → 300,19
}
}
 
printf("Country intl code.....: %03d\n", cntdata.id);
printf("Codepage..............: %d\n", cntdata.codepage);
printf("Decimal separator.....: %c\n", cntdata.decimal);
printf("Thousands separator...: %c\n", cntdata.thousands);
printf("Country intl code.....: %03d\n", cntdata.CTYINFO.id);
printf("Codepage..............: %d\n", cntdata.CTYINFO.codepage);
printf("Decimal separator.....: %c\n", cntdata.CTYINFO.decimal[0]);
printf("Thousands separator...: %c\n", cntdata.CTYINFO.thousands[0]);
printf("Date format...........: %s\n", datestring(&cntdata));
printf("Time format...........: %s\n", timestring(&cntdata));
printf("Yes/No letters........: %c/%c\n", cntdata.yes, cntdata.no);
printf("Yes/No letters........: %c/%c\n", cntdata.YESNO.yes[0], cntdata.YESNO.no[0]);
printf("Currency example......: %s\n", currencystring(&cntdata));
 
printf("\n"
"Please make sure your CONFIG.SYS contains a COUNTRY directive that points to\n"
"your custom preferences file:\n"
"COUNTRY=%03d,%03d,%s\n\n", cntdata.id, cntdata.codepage, fname);
"COUNTRY=%03d,%03d,%s\n\n", cntdata.CTYINFO.id, cntdata.CTYINFO.codepage, fname);
 
/* if anything changed, write the new file */
if (changedflag != 0) country_write(fname, &cntdata);