home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
mtools_3.6.src.lzh
/
MTOOLS_3.6
/
codepage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-11-14
|
4KB
|
222 lines
#include "sysincludes.h"
#include "mtools.h"
#include "codepage.h"
Codepage_t *Codepage=0;
char *mstoupper=0;
#undef WORD
#define WORD(x,y) (file[(x)+2*(y)] + (file[(x)+1+2*(y)] << 8))
#define COUNTRY(x) WORD(25+(x)*14, 1)
#define CODEPAGE(x) WORD(25+(x)*14, 2)
#define DATA(x) WORD(25+(x)*14, 5)
#define CTYINFO(x) WORD(DATA(x), 3)
#define CTYINFOCP(x) WORD(CTYINFO(x), 6)
#define UCASE(x) WORD(DATA(x), 11)
#define UCASEBYTE file[ucase+10+j*8+k]
#define NBVARS(x) WORD(DATA(x), 0)
#define VARID(x,y) WORD(DATA(x), y*4+2)
#define VARVAL(x,y) WORD(DATA(x), y*4+3)
static void bad_country_file(void)
{
fprintf(stderr,"Corrupted country.sys file\n");
exit(1);
}
static void not_found(int country_found, int country, int codepage)
{
if(!country_found)
fprintf(stderr,"Country code %03d not supported\n",
country);
else
fprintf(stderr,"Country/codepage combo %03d/%d not supported\n",
country, codepage);
exit(1);
}
static short get_variable(unsigned char *file, int i, int id)
{
int j;
for(j=0; j < NBVARS(i); j++)
if(VARID(i,j) == id)
return VARVAL(i,j);
return 0;
}
static void set_toupper_from_builtin(int country, int *codepage)
{
country_t *p;
int country_found = 0;
if(mstoupper)
return;
for(p = countries; p->country; p++) {
if(p->country == country) {
country_found = 1;
if(!*codepage)
*codepage = p->default_codepage;
if (p->codepage == *codepage) {
mstoupper = (char *) toucase[p->to_upper];
return;
}
}
}
not_found(country_found, country, *codepage);
}
static void load_toupper(int country, int *codepage, char *filename)
{
int fd, filesize;
unsigned char *file;
unsigned short ucase=0, records;
int i;
int country_found = 0;
struct stat buf;
if(!filename) {
set_toupper_from_builtin(country, codepage);
return;
}
fd = open(filename, O_RDONLY);
if(fd < 0) {
perror("open country.sys");
exit(1);
}
fstat(fd, &buf);
file = (unsigned char *) malloc(buf.st_size);
if(!file) {
fprintf(stderr, "Out of memory\n");
exit(1);
}
/* load country.sys */
filesize=read(fd, (char *) file, 65536);
if(filesize < 0) {
perror("Read country.sys\n");
exit(1);
}
close(fd);
if(strcmp((char *)file, "\377COUNTRY"))
bad_country_file();
records = WORD(23,0);
/* second pass: locate translation table */
for(i=0; i<records; i++) {
if(country == COUNTRY(i)) {
country_found = 1;
if(!*codepage)
*codepage = get_variable(file, i, 1);
if(mstoupper)
continue;
if(*codepage == CODEPAGE(i)) {
ucase = get_variable(file, i, 4);
if(!ucase) {
fprintf(stderr,
"No translation table for this"
"country and code page\n");
exit(1);
}
if(strncmp((char*)file+ucase+1, "UCASE", 5) &&
strncmp((char*)file+ucase+1, "FUCASE", 6))
bad_country_file();
mstoupper = (char *) toucase[0];
memcpy(mstoupper, file + ucase + 10, 128);
free(file);
return;
}
}
}
not_found(country_found, country, *codepage);
free(file);
}
static void set_codepage(int nr)
{
if(Codepage)
return;
for(Codepage = codepages; Codepage->nr; Codepage++)
if(Codepage->nr == nr)
return;
fprintf(stderr,"Unknown code page %d\n", nr);
exit(1);
}
static void syntax(void)
{
fprintf(stderr,"Syntax error in COUNTRY environmental variable\n");
fprintf(stderr,"Usage: export COUNTRY=countrycode[,[codepage][,filename]]\n");
exit(1);
}
void init_codepage(void)
{
char *country, *file;
int country_prefix;
int codepage;
file = 0;
country=country_string;
if(!country) {
codepage = 850;
country_prefix = 41; /* Switzerland */
} else {
file = 0;
codepage = 0;
country_prefix = strtoul(country, &country, 10);
if(!country_prefix)
syntax();
if(*country==',') {
country++;
codepage = strtoul(country, &country,10);
if(*country==',') {
file = country+1;
} else if (*country)
syntax();
} else if(*country)
syntax();
}
load_toupper(country_prefix, &codepage, file);
set_codepage(codepage);
}
unsigned char to_dos(unsigned char c)
{
int oc;
if(c < 0x80)
return c;
for(oc = 0 ; oc < 128; oc++) {
if(c == Codepage->tounix[oc])
return oc | 0x80;
}
return '_';
}
void to_unix(char *a, int n)
{
for( ; *a && n >= 0; n--, a++) {
/* special case, 0xE5 */
if(*a == 0x05)
*a = DELMARK;
if(*a & 0x80)
*a = (char) Codepage->tounix[(*a) & 0x7f];
}
}