1 /* aNetHack 0.0.1 celib.c $ANH-Date: 1432512803 2015/05/25 00:13:23 $ $ANH-Branch: master $:$ANH-Revision: 1.10 $ */
2 /* Copyright (C) 2001 by Alex Kompel */
3 /* aNetHack may be freely redistributed. See license for details. */
8 // #include "wceconf.h"
23 #define IS_LEAP(yr) (((yr) % 4 == 0 || (yr) % 100 == 0) && !(yr) % 400 == 0)
24 static char _day_mo_leap
[12] = { 31, 29, 31, 30, 31, 30,
25 31, 31, 30, 31, 30, 31 };
26 static char _day_mo
[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
28 struct tm
*__cdecl
localtime(const time_t *ptime
)
35 _t_cnv
.t_val
= *ptime
;
37 ptm
.tm_sec
= _t_cnv
.tm_val
.ss
; /* seconds after the minute - [0,59] */
38 ptm
.tm_min
= _t_cnv
.tm_val
.mm
; /* minutes after the hour - [0,59] */
39 ptm
.tm_hour
= _t_cnv
.tm_val
.hh
; /* hours since midnight - [0,23] */
40 ptm
.tm_mday
= _t_cnv
.tm_val
.dd
; /* day of the month - [1,31] */
41 ptm
.tm_mon
= _t_cnv
.tm_val
.mo
- 1; /* months since January - [0,11] */
42 ptm
.tm_year
= _t_cnv
.tm_val
.yr
; /* years since 1900 */
43 ptm
.tm_wday
= _t_cnv
.tm_val
.wd
; /* days since Sunday - [0,6] */
45 ptm
.tm_yday
= _t_cnv
.tm_val
.dd
; /* days since January 1 - [0,365] */
46 for (i
= 0; i
< ptm
.tm_mon
; i
++)
48 IS_LEAP(_t_cnv
.tm_val
.yr
+ 1900) ? _day_mo_leap
[i
] : _day_mo
[i
];
50 ptm
.tm_isdst
= 0; /* daylight savings time flag - NOT IMPLEMENTED */
54 time_t __cdecl
time(time_t *timeptr
)
59 _t_cnv
.tm_val
.yr
= stm
.wYear
- 1900;
60 _t_cnv
.tm_val
.mo
= stm
.wMonth
;
61 _t_cnv
.tm_val
.dd
= stm
.wDay
;
62 _t_cnv
.tm_val
.hh
= stm
.wHour
;
63 _t_cnv
.tm_val
.mm
= stm
.wMinute
;
64 _t_cnv
.tm_val
.ss
= stm
.wSecond
;
65 _t_cnv
.tm_val
.wd
= stm
.wDayOfWeek
;
68 *timeptr
= _t_cnv
.t_val
;
72 time_t __cdecl
mktime(struct tm
*tb
)
77 _t_cnv
.tm_val
.yr
= tb
->tm_year
;
78 _t_cnv
.tm_val
.mo
= tb
->tm_mon
;
79 _t_cnv
.tm_val
.dd
= tb
->tm_mday
;
80 _t_cnv
.tm_val
.hh
= tb
->tm_hour
;
81 _t_cnv
.tm_val
.mm
= tb
->tm_min
;
82 _t_cnv
.tm_val
.ss
= tb
->tm_sec
;
83 _t_cnv
.tm_val
.wd
= tb
->tm_wday
;
88 /*------------------------------------------------------------------------------*/
90 /* Hack io.h function with stdio.h functions */
91 /* ASSUMPTION : int can hold FILE* */
92 static TCHAR _nh_cwd
[MAX_PATH
];
93 const int MAGIC_OFFSET
= 5;
94 #define FILE_TABLE_SIZE 256
95 static HANDLE _nh_file_table
[FILE_TABLE_SIZE
];
96 static int file_pointer
= -1;
99 get_file_handle(int i
)
102 if (i
>= 0 && i
< FILE_TABLE_SIZE
)
103 return _nh_file_table
[i
];
105 return INVALID_HANDLE_VALUE
;
109 alloc_file_handle(HANDLE h
)
112 if (file_pointer
== -1) {
114 for (i
= 0; i
< FILE_TABLE_SIZE
; i
++)
115 _nh_file_table
[i
] = INVALID_HANDLE_VALUE
;
118 i
= (file_pointer
+ 1) % FILE_TABLE_SIZE
;
119 while (_nh_file_table
[i
] != INVALID_HANDLE_VALUE
) {
120 if (i
== file_pointer
) {
121 MessageBox(NULL
, _T("Ran out of file handles."),
122 _T("Fatal Error"), MB_OK
);
125 i
= (i
+ 1) % FILE_TABLE_SIZE
;
129 _nh_file_table
[file_pointer
] = h
;
130 return file_pointer
+ MAGIC_OFFSET
;
133 int __cdecl
close(int f
)
137 if (f
< 0 || f
>= FILE_TABLE_SIZE
)
139 retval
= (CloseHandle(_nh_file_table
[f
]) ? 0 : -1);
140 _nh_file_table
[f
] = INVALID_HANDLE_VALUE
;
144 int __cdecl
creat(const char *fname
, int mode
)
147 TCHAR wbuf
[MAX_PATH
+ 1];
148 ZeroMemory(wbuf
, sizeof(wbuf
));
149 NH_A2W(fname
, wbuf
, MAX_PATH
);
151 f
= CreateFile(wbuf
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
,
152 FILE_ATTRIBUTE_NORMAL
, NULL
);
154 if (f
== INVALID_HANDLE_VALUE
)
157 return alloc_file_handle(f
);
160 int __cdecl
eof(int f
)
163 HANDLE p
= get_file_handle(f
);
168 fpos
= SetFilePointer(p
, 0, NULL
, FILE_CURRENT
);
169 fsize
= SetFilePointer(p
, 0, NULL
, FILE_END
);
170 if (fpos
== 0xFFFFFFFF || fsize
== 0xFFFFFFFF)
175 SetFilePointer(p
, fpos
, NULL
, FILE_BEGIN
);
180 long __cdecl
lseek(int f
, long offset
, int origin
)
182 HANDLE p
= get_file_handle(f
);
186 fpos
= SetFilePointer(p
, offset
, NULL
, FILE_BEGIN
);
189 fpos
= SetFilePointer(p
, offset
, NULL
, FILE_CURRENT
);
192 fpos
= SetFilePointer(p
, offset
, NULL
, FILE_END
);
198 if (fpos
== 0xFFFFFFFF)
204 int __cdecl
open(const char *filename
, int oflag
, ...)
206 TCHAR fname
[MAX_PATH
+ 1];
207 TCHAR path
[MAX_PATH
+ 1];
212 /* O_TEXT is not supported */
215 * decode the access flags
217 switch (oflag
& (_O_RDONLY
| _O_WRONLY
| _O_RDWR
)) {
218 case _O_RDONLY
: /* read access */
219 fileaccess
= GENERIC_READ
;
221 case _O_WRONLY
: /* write access */
222 fileaccess
= GENERIC_READ
| GENERIC_WRITE
;
224 case _O_RDWR
: /* read and write access */
225 fileaccess
= GENERIC_READ
| GENERIC_WRITE
;
227 default: /* error, bad oflag */
232 * decode open/create method flags
234 switch (oflag
& (_O_CREAT
| _O_EXCL
| _O_TRUNC
)) {
236 case _O_EXCL
: // ignore EXCL w/o CREAT
237 filecreate
= OPEN_EXISTING
;
241 filecreate
= OPEN_ALWAYS
;
244 case _O_CREAT
| _O_EXCL
:
245 case _O_CREAT
| _O_TRUNC
| _O_EXCL
:
246 filecreate
= CREATE_NEW
;
250 case _O_TRUNC
| _O_EXCL
: // ignore EXCL w/o CREAT
251 filecreate
= TRUNCATE_EXISTING
;
254 case _O_CREAT
| _O_TRUNC
:
255 filecreate
= CREATE_ALWAYS
;
262 /* assemple the file name */
263 ZeroMemory(fname
, sizeof(fname
));
264 ZeroMemory(path
, sizeof(path
));
265 NH_A2W(filename
, fname
, MAX_PATH
);
266 if (*filename
!= '\\' && *filename
!= '/') {
267 _tcscpy(path
, _nh_cwd
);
268 _tcsncat(path
, _T("\\"), MAX_PATH
- _tcslen(path
));
270 _tcsncat(path
, fname
, MAX_PATH
- _tcslen(path
));
273 * try to open/create the file
275 if ((f
= CreateFile(path
, fileaccess
, 0, NULL
, filecreate
,
276 FILE_ATTRIBUTE_NORMAL
, NULL
))
277 == INVALID_HANDLE_VALUE
) {
281 if (!(oflag
& O_APPEND
))
282 SetFilePointer(f
, 0, NULL
, FILE_BEGIN
);
283 return alloc_file_handle(f
);
286 int __cdecl
read(int f
, void *buffer
, unsigned int count
)
288 HANDLE p
= get_file_handle(f
);
290 if (!ReadFile(p
, buffer
, count
, &bytes_read
, NULL
))
293 return (int) bytes_read
;
296 int __cdecl
unlink(const char *filename
)
298 TCHAR wbuf
[MAX_PATH
+ 1];
299 TCHAR fname
[MAX_PATH
+ 1];
301 ZeroMemory(wbuf
, sizeof(wbuf
));
302 ZeroMemory(fname
, sizeof(fname
));
303 NH_A2W(filename
, wbuf
, MAX_PATH
);
304 if (*filename
!= '\\' && *filename
!= '/') {
305 _tcscpy(fname
, _nh_cwd
);
306 _tcsncat(fname
, _T("\\"), MAX_PATH
- _tcslen(fname
));
308 _tcsncat(fname
, wbuf
, MAX_PATH
- _tcslen(fname
));
310 return !DeleteFileW(fname
);
313 int __cdecl
write(int f
, const void *buffer
, unsigned int count
)
315 HANDLE p
= get_file_handle(f
);
317 if (!WriteFile(p
, buffer
, count
, &bytes_written
, NULL
))
320 return (int) bytes_written
;
323 int __cdecl
rename(const char *oldname
, const char *newname
)
325 WCHAR f1
[MAX_PATH
+ 1];
326 WCHAR f2
[MAX_PATH
+ 1];
327 ZeroMemory(f1
, sizeof(f1
));
328 ZeroMemory(f2
, sizeof(f2
));
329 MultiByteToWideChar(CP_ACP
, 0, oldname
, -1, f1
, MAX_PATH
);
330 MultiByteToWideChar(CP_ACP
, 0, newname
, -1, f2
, MAX_PATH
);
331 return !MoveFile(f1
, f2
);
334 int __cdecl
access(const char *path
, int mode
)
337 WCHAR f
[MAX_PATH
+ 1];
338 ZeroMemory(f
, sizeof(f
));
339 MultiByteToWideChar(CP_ACP
, 0, path
, -1, f
, MAX_PATH
);
341 attr
= GetFileAttributes(f
);
342 if (attr
== (DWORD
) -1)
345 if ((attr
& FILE_ATTRIBUTE_READONLY
) && (mode
& 2))
352 chdir(const char *dirname
)
354 ZeroMemory(_nh_cwd
, sizeof(_nh_cwd
));
355 NH_A2W(dirname
, _nh_cwd
, MAX_PATH
);
360 getcwd(char *buffer
, int maxlen
)
362 if (maxlen
< (int) _tcslen(_nh_cwd
))
365 return NH_W2A(_nh_cwd
, buffer
, maxlen
);
368 /*------------------------------------------------------------------------------*/
372 /*------------------------------------------------------------------------------*/
374 * Chdrive() changes the default drive.
383 * This is used in nhlan.c to implement some of the LAN_FEATURES.
386 get_username(lan_username_size
)
387 int *lan_username_size
;
389 static char username_buffer
[BUFSZ
];
390 strcpy(username_buffer
, "nhsave");
391 return username_buffer
;
411 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
412 int __cdecl
isupper(int c
)
419 NH_A2W(str
, wstr
, 1);
420 return iswupper(wstr
[0]);
423 int __cdecl
isdigit(int c
)
425 return ('0' <= c
&& c
<= '9');
428 int __cdecl
isxdigit(int c
)
430 return (('0' <= c
&& c
<= '9') || ('a' <= c
&& c
<= 'f')
431 || ('A' <= c
&& c
<= 'F'));
434 int __cdecl
isspace(int c
)
441 NH_A2W(str
, wstr
, 1);
442 return iswspace(wstr
[0]);
445 int __cdecl
isprint(int c
)
452 NH_A2W(str
, wstr
, 1);
453 return iswprint(wstr
[0]);
456 char *__cdecl
_strdup(const char *s
)
459 p
= malloc(strlen(s
) + 1);
463 char *__cdecl
strrchr(const char *s
, int c
)
467 w
= wcsrchr(NH_A2W(s
, wstr
, 1024), c
);
469 return (char *) (s
+ (w
- wstr
));
474 int __cdecl
_stricmp(const char *a
, const char *b
)
476 return strncmpi(a
, b
, 65535u);
481 #if defined(WIN_CE_PS2xx)
482 /* stdio.h functions are missing from PAlm Size PC SDK 1.2 (SH3 and MIPS) */
484 #pragma warning(disable : 4273)
486 FILE *__cdecl
fopen(const char *filename
, const char *mode
)
492 /* First mode character must be 'r', 'w', or 'a'. */
495 modeflag
= _O_RDONLY
;
498 modeflag
= _O_WRONLY
| _O_CREAT
| _O_TRUNC
;
501 modeflag
= _O_WRONLY
| _O_CREAT
| _O_APPEND
;
508 while (*++mode
&& whileflag
)
511 if (modeflag
& _O_RDWR
)
515 modeflag
&= ~(_O_RDONLY
| _O_WRONLY
);
520 if (modeflag
& (_O_TEXT
| _O_BINARY
))
523 modeflag
|= _O_BINARY
;
526 case 't': /* not supported */
535 if ((filedes
= open(filename
, modeflag
)) == -1)
538 return (FILE *) filedes
;
541 int __cdecl
fscanf(FILE *f
, const char *format
, ...)
543 /* Format spec: %[*] [width] [l] type ] */
556 #define RETURN_SCANF(i) \
561 #define NEXT_CHAR(f) (n_read++, fgetc(f))
563 va_start(args
, format
);
567 while (ch
&& sch
!= EOF
) {
569 while (ch
&& isspace(ch
))
571 while (sch
!= EOF
&& isspace(sch
))
580 RETURN_SCANF(matched
);
588 RETURN_SCANF(matched
);
594 /* read skip flag - '*' */
602 while (ch
&& isdigit(ch
)) {
603 width
= width
* 10 + (ch
- '0');
618 *(va_arg(args
, char *) ) = sch
;
626 while (sch
!= EOF
&& isspace(sch
))
628 while (sch
!= EOF
&& isdigit(sch
) && --width
>= 0) {
635 if (modifier
== 'l') {
636 *(va_arg(args
, long *) ) =
637 wcstol(NH_A2W(buf
, wbuf
, BUFSZ
), NULL
, 10);
639 *(va_arg(args
, int *) ) =
640 wcstol(NH_A2W(buf
, wbuf
, BUFSZ
), NULL
, 10);
646 while (sch
!= EOF
&& isspace(sch
))
648 while (sch
!= EOF
&& isxdigit(sch
) && --width
>= 0) {
655 if (modifier
== 'l') {
656 *(va_arg(args
, long *) ) =
657 wcstol(NH_A2W(buf
, wbuf
, BUFSZ
), NULL
, 16);
659 *(va_arg(args
, int *) ) =
660 wcstol(NH_A2W(buf
, wbuf
, BUFSZ
), NULL
, 16);
665 *(va_arg(args
, int *) ) = n_read
;
670 while (sch
!= EOF
&& !isspace(sch
) && --width
>= 0) {
674 p
= va_arg(args
, char *);
675 while (sch
!= EOF
&& !isspace(sch
) && --width
>= 0) {
688 ZeroMemory(pattern
, sizeof(pattern
));
691 /* try to parse '^' modifier */
702 for (; ch
&& ch
!= ']'; ch
= *format
++) {
703 /* try to parse range: a-z */
704 if (format
[0] == '-' && format
[1] && format
[1] != ']') {
708 while (start
<= end
) {
709 if (!strchr(pattern
, (char) start
))
714 if (!strchr(pattern
, (char) ch
))
720 while (sch
!= EOF
&& strchr(pattern
, sch
)
725 p
= va_arg(args
, char *);
727 while (sch
!= EOF
&& !strchr(pattern
, sch
)
733 while (sch
!= EOF
&& strchr(pattern
, sch
)
754 fseek(f
, -1, SEEK_CUR
);
755 RETURN_SCANF(matched
);
761 int __cdecl
fprintf(FILE *f
, const char *format
, ...)
769 va_start(args
, format
);
770 retval
= vfprintf(f
, format
, args
);
776 int __cdecl
vfprintf(FILE *f
, const char *format
, va_list args
)
784 retval
= vsprintf(buf
, format
, args
);
786 write((int) f
, buf
, strlen(buf
));
791 int __cdecl
fgetc(FILE *f
)
798 if (read(fh
, &c
, 1) == 1)
804 char *__cdecl
fgets(char *s
, int size
, FILE *f
)
806 /* not the best performance but it will do for now...*/
808 if (!f
|| !s
|| size
== 0)
811 if ((c
= fgetc(f
)) == EOF
)
822 int __cdecl
printf(const char *format
, ...)
830 va_start(args
, format
);
831 retval
= vprintf(format
, args
);
837 int __cdecl
vprintf(const char *format
, va_list args
)
842 retval
= vsprintf(buf
, format
, args
);
847 // int __cdecl putchar(int);
848 int __cdecl
puts(const char *s
)
851 NH_A2W(s
, wbuf
, 4096);
852 MessageBox(NULL
, wbuf
, _T("stdout"), MB_OK
);
856 FILE *__cdecl
_getstdfilex(int desc
)
861 int __cdecl
fclose(FILE *f
)
865 return close((int) f
) == -1 ? EOF
: 0;
868 size_t __cdecl
fread(void *p
, size_t size
, size_t count
, FILE *f
)
871 if (!f
|| !p
|| size
== 0 || count
== 0)
873 read_bytes
= read((int) f
, p
, size
* count
);
874 return read_bytes
> 0 ? (read_bytes
/ size
) : 0;
877 size_t __cdecl
fwrite(const void *p
, size_t size
, size_t count
, FILE *f
)
880 if (!f
|| !p
|| size
== 0 || count
== 0)
882 write_bytes
= write((int) f
, p
, size
* count
);
883 return write_bytes
> 0 ? write_bytes
/ size
: 0;
886 int __cdecl
fflush(FILE *f
)
891 int __cdecl
feof(FILE *f
)
893 return (f
&& eof((int) f
) == 0) ? 0 : 1;
896 int __cdecl
fseek(FILE *f
, long offset
, int from
)
898 return (f
&& lseek((int) f
, offset
, from
) >= 0) ? 0 : 1;
901 long __cdecl
ftell(FILE *f
)
903 return f
? lseek((int) f
, 0, SEEK_CUR
) : -1;