Files
nethack/sys/wince/celib.c
2003-02-13 05:10:21 +00:00

825 lines
18 KiB
C

/* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
/* NetHack may be freely redistributed. See license for details. */
#define NEED_VARARGS
#include "hack.h"
#include <fcntl.h>
// #include "wceconf.h"
static union {
time_t t_val;
struct time_pack {
unsigned int ss:6;
unsigned int mm:6;
unsigned int dd:5;
unsigned int hh:6;
unsigned int mo:4;
unsigned int yr:10;
unsigned int wd:3;
} tm_val;
} _t_cnv;
#define IS_LEAP(yr) (((yr)%4==0 || (yr)%100==0) && !(yr)%400==0)
static char _day_mo_leap[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static char _day_mo[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
struct tm * __cdecl localtime ( const time_t *ptime )
{
static struct tm ptm;
int i;
if( !ptime ) return NULL;
_t_cnv.t_val = *ptime;
ptm.tm_sec = _t_cnv.tm_val.ss ; /* seconds after the minute - [0,59] */
ptm.tm_min = _t_cnv.tm_val.mm; /* minutes after the hour - [0,59] */
ptm.tm_hour = _t_cnv.tm_val.hh; /* hours since midnight - [0,23] */
ptm.tm_mday = _t_cnv.tm_val.dd; /* day of the month - [1,31] */
ptm.tm_mon = _t_cnv.tm_val.mo-1; /* months since January - [0,11] */
ptm.tm_year = _t_cnv.tm_val.yr; /* years since 1900 */
ptm.tm_wday = _t_cnv.tm_val.wd; /* days since Sunday - [0,6] */
ptm.tm_yday = _t_cnv.tm_val.dd; /* days since January 1 - [0,365] */
for( i=0; i<ptm.tm_mon; i++ )
ptm.tm_yday += IS_LEAP(_t_cnv.tm_val.yr+1900)?_day_mo_leap[i] : _day_mo[i] ;
ptm.tm_isdst = 0; /* daylight savings time flag - NOT IMPLEMENTED */
return &ptm;
}
time_t __cdecl time(time_t * timeptr)
{
SYSTEMTIME stm;
GetLocalTime(&stm);
_t_cnv.tm_val.yr = stm.wYear-1900;
_t_cnv.tm_val.mo = stm.wMonth;
_t_cnv.tm_val.dd = stm.wDay;
_t_cnv.tm_val.hh = stm.wHour;
_t_cnv.tm_val.mm = stm.wMinute;
_t_cnv.tm_val.ss = stm.wSecond;
_t_cnv.tm_val.wd = stm.wDayOfWeek;
if( timeptr)
*timeptr = _t_cnv.t_val;
return _t_cnv.t_val;
}
/*------------------------------------------------------------------------------*/
/* __io.h__ */
/* Hack io.h function with stdio.h functions */
/* ASSUMPTION : int can hold FILE* */
static TCHAR _nh_cwd[MAX_PATH];
const int MAGIC_OFFSET=5;
#define FILE_TABLE_SIZE 256
static HANDLE _nh_file_table[FILE_TABLE_SIZE];
static int file_pointer = -1;
static HANDLE get_file_handle(int i)
{
i -= MAGIC_OFFSET;
if( i>=0 && i<FILE_TABLE_SIZE )
return _nh_file_table[i];
else
return INVALID_HANDLE_VALUE;
}
static int alloc_file_handle(HANDLE h)
{
int i;
if( file_pointer==-1 ) {
file_pointer=0;
for(i=0; i<FILE_TABLE_SIZE; i++ )
_nh_file_table[i] = INVALID_HANDLE_VALUE;
}
i = (file_pointer+1)%FILE_TABLE_SIZE;
while(_nh_file_table[i]!=INVALID_HANDLE_VALUE ) {
if( i==file_pointer ) {
MessageBox(NULL, _T("Ran out of file handles."), _T("Fatal Error"), MB_OK);
abort();
}
i = (i+1) % FILE_TABLE_SIZE;
}
file_pointer = i;
_nh_file_table[file_pointer] = h;
return file_pointer+MAGIC_OFFSET;
}
int __cdecl close(int f) {
int retval;
f -= MAGIC_OFFSET;
if( f<0 || f>=FILE_TABLE_SIZE ) return -1;
retval = (CloseHandle(_nh_file_table[f])? 0 : -1);
_nh_file_table[f] = INVALID_HANDLE_VALUE;
return retval;
}
int __cdecl creat(const char *fname , int mode)
{
HANDLE f;
TCHAR wbuf[MAX_PATH+1];
ZeroMemory(wbuf, sizeof(wbuf));
NH_A2W(fname, wbuf, MAX_PATH);
f = CreateFile(
wbuf,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if( f==INVALID_HANDLE_VALUE ) return -1;
else return alloc_file_handle(f);
}
int __cdecl eof(int f)
{
DWORD fpos, fsize;
HANDLE p = get_file_handle(f);
if( f==-1 ) return -1;
fpos = SetFilePointer(p, 0, NULL, FILE_CURRENT);
fsize = SetFilePointer(p, 0, NULL, FILE_END);
if( fpos==0xFFFFFFFF || fsize==0xFFFFFFFF ) return -1;
if( fpos==fsize ) return 1;
else {
SetFilePointer(p, fpos, NULL, FILE_BEGIN);
return 0;
}
}
long __cdecl lseek( int f, long offset, int origin )
{
HANDLE p = get_file_handle(f);
DWORD fpos;
switch(origin) {
case SEEK_SET:
fpos = SetFilePointer(p, offset, NULL, FILE_BEGIN);
break;
case SEEK_CUR:
fpos = SetFilePointer(p, offset, NULL, FILE_CURRENT);
break;
case SEEK_END:
fpos = SetFilePointer(p, offset, NULL, FILE_END);
break;
default:
fpos = 0xFFFFFFFF;
break;
}
if( fpos==0xFFFFFFFF ) return -1;
else return (long)fpos;
}
int __cdecl open( const char *filename, int oflag, ... )
{
TCHAR fname[MAX_PATH+1];
TCHAR path[MAX_PATH+1];
HANDLE f;
DWORD fileaccess;
DWORD filecreate;
/* O_TEXT is not supported */
/*
* decode the access flags
*/
switch( oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR) ) {
case _O_RDONLY: /* read access */
fileaccess = GENERIC_READ;
break;
case _O_WRONLY: /* write access */
fileaccess = GENERIC_READ | GENERIC_WRITE;
break;
case _O_RDWR: /* read and write access */
fileaccess = GENERIC_READ | GENERIC_WRITE;
break;
default: /* error, bad oflag */
return -1;
}
/*
* decode open/create method flags
*/
switch ( oflag & (_O_CREAT | _O_EXCL | _O_TRUNC) ) {
case 0:
case _O_EXCL: // ignore EXCL w/o CREAT
filecreate = OPEN_EXISTING;
break;
case _O_CREAT:
filecreate = OPEN_ALWAYS;
break;
case _O_CREAT | _O_EXCL:
case _O_CREAT | _O_TRUNC | _O_EXCL:
filecreate = CREATE_NEW;
break;
case _O_TRUNC:
case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
filecreate = TRUNCATE_EXISTING;
break;
case _O_CREAT | _O_TRUNC:
filecreate = CREATE_ALWAYS;
break;
default:
return -1;
}
/* assemple the file name */
ZeroMemory(fname, sizeof(fname));
ZeroMemory(path, sizeof(path));
NH_A2W(filename, fname, MAX_PATH);
if( *filename!='\\' && *filename!='/' ) {
_tcscpy(path, _nh_cwd);
_tcsncat(path, _T("\\"), MAX_PATH - _tcslen(path));
}
_tcsncat(path, fname, MAX_PATH - _tcslen(path));
/*
* try to open/create the file
*/
if ( (f = CreateFile( path,
fileaccess,
0,
NULL,
filecreate,
FILE_ATTRIBUTE_NORMAL,
NULL ))
== INVALID_HANDLE_VALUE )
{
return -1;
}
if( !(oflag & O_APPEND) ) SetFilePointer(f, 0, NULL, FILE_BEGIN);
return alloc_file_handle(f);
}
int __cdecl read( int f, void *buffer, unsigned int count )
{
HANDLE p = get_file_handle(f);
DWORD bytes_read;
if( !ReadFile(p, buffer, count, &bytes_read, NULL) )
return -1;
else
return (int)bytes_read;
}
int __cdecl unlink(const char * filename)
{
TCHAR wbuf[MAX_PATH+1];
TCHAR fname[MAX_PATH+1];
ZeroMemory(wbuf, sizeof(wbuf));
ZeroMemory(fname, sizeof(fname));
NH_A2W(filename, wbuf, MAX_PATH);
if( *filename!='\\' && *filename!='/' ) {
_tcscpy(fname, _nh_cwd);
_tcsncat(fname, _T("\\"), MAX_PATH - _tcslen(fname));
}
_tcsncat(fname, wbuf, MAX_PATH - _tcslen(fname));
return !DeleteFileW(fname);
}
int __cdecl write( int f, const void *buffer, unsigned int count )
{
HANDLE p = get_file_handle(f);
DWORD bytes_written;
if( !WriteFile(p, buffer, count, &bytes_written, NULL) )
return -1;
else
return (int)bytes_written;
}
int __cdecl rename( const char *oldname, const char *newname )
{
WCHAR f1[MAX_PATH+1];
WCHAR f2[MAX_PATH+1];
ZeroMemory(f1, sizeof(f1));
ZeroMemory(f2, sizeof(f2));
MultiByteToWideChar(CP_ACP, 0, oldname, -1, f1, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, newname, -1, f2, MAX_PATH);
return !MoveFile(f1, f2);
}
int __cdecl access( const char *path, int mode )
{
DWORD attr;
WCHAR f[MAX_PATH+1];
ZeroMemory(f, sizeof(f));
MultiByteToWideChar(CP_ACP, 0, path, -1, f, MAX_PATH);
attr = GetFileAttributes(f);
if( attr == (DWORD)-1 ) return -1;
if ( (attr & FILE_ATTRIBUTE_READONLY) && (mode & 2) )
return -1;
else
return 0;
}
int chdir( const char *dirname )
{
ZeroMemory(_nh_cwd, sizeof(_nh_cwd));
NH_A2W(dirname, _nh_cwd, MAX_PATH);
return 0;
}
char *getcwd( char *buffer, int maxlen )
{
if( maxlen<(int)_tcslen(_nh_cwd) ) return NULL;
else return NH_W2A(_nh_cwd, buffer, maxlen);
}
/*------------------------------------------------------------------------------*/
/* __errno.h__ */
int errno;
/*------------------------------------------------------------------------------*/
/*
* Chdrive() changes the default drive.
*/
void
chdrive(char *str)
{
return;
}
/*
* This is used in nhlan.c to implement some of the LAN_FEATURES.
*/
char *get_username(lan_username_size)
int *lan_username_size;
{
static char username_buffer[BUFSZ];
strcpy(username_buffer, "nhsave");
return username_buffer;
}
void Delay(int ms)
{
(void)Sleep(ms);
}
void more()
{
}
int isatty(int f)
{
return 0;
}
#if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
int __cdecl isupper(int c)
{
char str[2];
WCHAR wstr[2];
str[0] = c;
str[1] = 0;
NH_A2W(str, wstr, 1);
return iswupper(wstr[0]);
}
int __cdecl isdigit(int c)
{
return ('0' <= c && c <= '9');
}
int __cdecl isxdigit(int c)
{
return (('0' <= c && c <= '9') ||
('a' <= c && c <= 'f') ||
('A' <= c && c <= 'F'));
}
int __cdecl isspace(int c)
{
char str[2];
WCHAR wstr[2];
str[0] = c;
str[1] = 0;
NH_A2W(str, wstr, 1);
return iswspace(wstr[0]);
}
int __cdecl isprint(int c)
{
char str[2];
WCHAR wstr[2];
str[0] = c;
str[1] = 0;
NH_A2W(str, wstr, 1);
return iswprint(wstr[0]);
}
char* __cdecl _strdup(const char* s)
{
char* p;
p = malloc(strlen(s)+1);
return strcpy(p, s);
}
char* __cdecl strrchr( const char *s, int c )
{
WCHAR wstr[1024];
WCHAR *w;
w = wcsrchr(NH_A2W(s, wstr, 1024), c);
if(w) return (char*)(s + (w - wstr));
else return NULL;
}
int __cdecl _stricmp(const char* a, const char* b)
{
return strncmpi(a, b, 65535u);
}
#endif
#if defined(WIN_CE_PS2xx)
/* stdio.h functions are missing from PAlm Size PC SDK 1.2 (SH3 and MIPS) */
#pragma warning(disable:4273)
FILE * __cdecl fopen(const char* filename, const char *mode)
{
int modeflag;
int whileflag;
int filedes;
/* First mode character must be 'r', 'w', or 'a'. */
switch (*mode) {
case 'r':
modeflag = _O_RDONLY;
break;
case 'w':
modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
break;
case 'a':
modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
break;
default:
return NULL;
}
whileflag=1;
while(*++mode && whileflag)
switch(*mode) {
case '+':
if (modeflag & _O_RDWR)
whileflag=0;
else {
modeflag |= _O_RDWR;
modeflag &= ~(_O_RDONLY | _O_WRONLY);
}
break;
case 'b':
if (modeflag & (_O_TEXT | _O_BINARY))
whileflag=0;
else
modeflag |= _O_BINARY;
break;
case 't': /* not supported */
whileflag=0;
break;
default:
whileflag=0;
break;
}
if ((filedes = open(filename, modeflag))==-1) return NULL;
return (FILE*)filedes;
}
int __cdecl fscanf(FILE *f , const char *format, ...)
{
/* Format spec: %[*] [width] [l] type ] */
int ch;
int sch;
int matched = 0;
int width = 65535;
int modifier = -1;
int skip_flag = 0;
int n_read = 0;
char buf[BUFSZ];
TCHAR wbuf[BUFSZ];
char* p;
va_list args;
#define RETURN_SCANF(i) { va_end(args); return i; }
#define NEXT_CHAR(f) (n_read++, fgetc(f))
va_start(args, format);
ch = *format++;
sch = NEXT_CHAR(f);
while( ch && sch!=EOF ) {
if( isspace(ch) ) {
while( ch && isspace(ch) ) ch = *format++;
while( sch!=EOF && isspace(sch) ) sch = NEXT_CHAR(f);
format--;
goto next_spec;
}
/* read % */
if( ch!='%' ) {
if( sch!=ch ) RETURN_SCANF(matched);
sch = NEXT_CHAR(f);
goto next_spec;
} else {
/* process '%%' */
ch = *format++;
if( ch=='%' ) {
if( sch!='%' ) RETURN_SCANF(matched);
sch = NEXT_CHAR(f);
goto next_spec;
}
if( ch=='*' ) {
/* read skip flag - '*' */
skip_flag=1;
ch = *format++;
}
/* get width */
if( isdigit(ch) ) {
width = 0;
while(ch && isdigit(ch)) {
width = width*10 + (ch-'0');
ch = *format++;
}
}
/* get modifier */
if( ch=='l' ) {
modifier = 'l';
ch = *format++;
}
/* get type */
switch(ch) {
case 'c':
if( !skip_flag ) {
*(va_arg(args, char*))=sch;
matched++;
}
sch = NEXT_CHAR(f);
goto next_spec;
case 'd':
p = buf;
/* skip space */
while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
while(sch!=EOF && isdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
*p = '\x0';
if( !skip_flag ) {
matched++;
if( modifier=='l' ) {
*(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
} else {
*(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
}
}
goto next_spec;
case 'x':
p = buf;
while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
while(sch!=EOF && isxdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
*p = '\x0';
if( !skip_flag ) {
matched++;
if( modifier=='l' ) {
*(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
} else {
*(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
}
}
goto next_spec;
case 'n':
*(va_arg(args, int*)) = n_read;
matched++;
goto next_spec;
case 's':
if( skip_flag ) {
while(sch!=EOF && !isspace(sch) && --width>=0) { sch=NEXT_CHAR(f); }
} else {
p = va_arg(args, char*);
while(sch!=EOF && !isspace(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
*p = '\x0';
matched++;
}
goto next_spec;
case '[': {
char pattern[256];
int start, end;
int negate;
ZeroMemory(pattern, sizeof(pattern));
p = pattern;
/* try to parse '^' modifier */
ch = *format++;
if( ch=='^' ) { negate=1; ch=*format++; }
else { negate=0; }
if( ch==0 ) RETURN_SCANF(EOF);
for( ; ch && ch!=']'; ch = *format++ ) {
/* try to parse range: a-z */
if( format[0]=='-' &&
format[1] && format[1]!=']' ) {
start = ch;
format++;
end = *format++;
while(start<=end) {
if(!strchr(pattern, (char)start))
*p++ = (char)start;
start++;
}
} else {
if(!strchr(pattern, (char)ch)) *p++ = (char)ch;
}
}
if( skip_flag ) {
while(sch!=EOF && strchr(pattern, sch) && --width>=0) { sch=NEXT_CHAR(f); }
} else {
p = va_arg(args, char*);
if( negate )
while(sch!=EOF && !strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
else
while(sch!=EOF && strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
*p = '\x0';
matched++;
}
} goto next_spec;
default:
RETURN_SCANF(EOF);
}
}
next_spec:
width = 65535;
modifier = -1;
skip_flag = 0;
ch = *format++;
}
fseek(f, -1, SEEK_CUR);
RETURN_SCANF(matched);
#undef RETURN_SCANF
#undef NEXT_CHAR
}
int __cdecl fprintf(FILE *f , const char *format, ...)
{
int retval;
va_list args;
if( !f || !format ) return 0;
va_start(args, format);
retval = vfprintf(f, format, args);
va_end(args);
return retval;
}
int __cdecl vfprintf(FILE* f, const char *format, va_list args)
{
char buf[4096];
int retval;
if( !f || !format ) return 0;
retval = vsprintf(buf, format, args);
write((int)f, buf, strlen(buf));
return retval;
}
int __cdecl fgetc(FILE * f)
{
char c;
int fh = (int)f;
if( !f ) return EOF;
if( read(fh, &c, 1)==1 ) return c;
else return EOF;
}
char * __cdecl fgets(char *s, int size, FILE *f)
{
/* not the best performance but it will do for now...*/
char c;
if( !f || !s || size==0 ) return NULL;
while( --size>0 ) {
if( (c = fgetc(f))==EOF ) return NULL;
*s++ = c;
if( c=='\n' ) break;
}
*s = '\x0';
return s;
}
int __cdecl printf(const char *format, ...)
{
int retval;
va_list args;
if( !format ) return 0;
va_start(args, format);
retval = vprintf(format, args);
va_end(args);
return retval;
}
int __cdecl vprintf(const char *format, va_list args)
{
char buf[4096];
int retval;
retval = vsprintf(buf, format, args);
puts(buf);
return retval;
}
// int __cdecl putchar(int);
int __cdecl puts(const char * s)
{
TCHAR wbuf[4096];
NH_A2W(s, wbuf, 4096);
MessageBox(NULL, wbuf, _T("stdout"), MB_OK);
return 0;
}
FILE* __cdecl _getstdfilex(int desc)
{
return NULL;
}
int __cdecl fclose(FILE * f)
{
if(!f) return EOF;
return close((int)f)==-1? EOF : 0;
}
size_t __cdecl fread(void *p, size_t size, size_t count, FILE *f)
{
int read_bytes;
if(!f || !p || size==0 || count==0) return 0;
read_bytes = read((int)f, p, size*count);
return read_bytes>0? (read_bytes/size) : 0;
}
size_t __cdecl fwrite(const void *p, size_t size, size_t count, FILE * f)
{
int write_bytes;
if(!f || !p || size==0 || count==0) return 0;
write_bytes = write((int)f, p, size*count);
return write_bytes>0? write_bytes/size : 0;
}
int __cdecl fflush(FILE *f)
{
return 0;
}
int __cdecl feof(FILE *f)
{
return (f && eof((int)f)==0)? 0 : 1;
}
int __cdecl fseek(FILE *f, long offset, int from)
{
return (f && lseek((int)f, offset, from)>=0)? 0 : 1;
}
long __cdecl ftell(FILE * f)
{
return f? lseek((int)f, 0, SEEK_CUR) : -1;
}
#endif