1 /* Copyright (C) 2001 by Alex Kompel <shurikk@pacbell.net> */
2 /* NetHack may be freely redistributed. See license for details. */
3
4 #define NEED_VARARGS
5 #include "hack.h"
6 #include <fcntl.h>
7 // #include "wceconf.h"
8
9 static union {
10 time_t t_val;
11 struct time_pack {
12 unsigned int ss:6;
13 unsigned int mm:6;
14 unsigned int dd:5;
15 unsigned int hh:6;
16 unsigned int mo:4;
17 unsigned int yr:10;
18 unsigned int wd:3;
19 } tm_val;
20 } _t_cnv;
21
22 #define IS_LEAP(yr) (((yr)%4==0 || (yr)%100==0) && !(yr)%400==0)
23 static char _day_mo_leap[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
24 static char _day_mo[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
25
localtime(const time_t * ptime)26 struct tm * __cdecl localtime ( const time_t *ptime )
27 {
28 static struct tm ptm;
29 int i;
30 if( !ptime ) return NULL;
31
32 _t_cnv.t_val = *ptime;
33
34 ptm.tm_sec = _t_cnv.tm_val.ss ; /* seconds after the minute - [0,59] */
35 ptm.tm_min = _t_cnv.tm_val.mm; /* minutes after the hour - [0,59] */
36 ptm.tm_hour = _t_cnv.tm_val.hh; /* hours since midnight - [0,23] */
37 ptm.tm_mday = _t_cnv.tm_val.dd; /* day of the month - [1,31] */
38 ptm.tm_mon = _t_cnv.tm_val.mo-1; /* months since January - [0,11] */
39 ptm.tm_year = _t_cnv.tm_val.yr; /* years since 1900 */
40 ptm.tm_wday = _t_cnv.tm_val.wd; /* days since Sunday - [0,6] */
41
42 ptm.tm_yday = _t_cnv.tm_val.dd; /* days since January 1 - [0,365] */
43 for( i=0; i<ptm.tm_mon; i++ )
44 ptm.tm_yday += IS_LEAP(_t_cnv.tm_val.yr+1900)?_day_mo_leap[i] : _day_mo[i] ;
45
46 ptm.tm_isdst = 0; /* daylight savings time flag - NOT IMPLEMENTED */
47 return &ptm;
48 }
49
time(time_t * timeptr)50 time_t __cdecl time(time_t * timeptr)
51 {
52 SYSTEMTIME stm;
53 GetLocalTime(&stm);
54
55 _t_cnv.tm_val.yr = stm.wYear-1900;
56 _t_cnv.tm_val.mo = stm.wMonth;
57 _t_cnv.tm_val.dd = stm.wDay;
58 _t_cnv.tm_val.hh = stm.wHour;
59 _t_cnv.tm_val.mm = stm.wMinute;
60 _t_cnv.tm_val.ss = stm.wSecond;
61 _t_cnv.tm_val.wd = stm.wDayOfWeek;
62
63 if( timeptr)
64 *timeptr = _t_cnv.t_val;
65 return _t_cnv.t_val;
66 }
67
68 /*------------------------------------------------------------------------------*/
69 /* __io.h__ */
70 /* Hack io.h function with stdio.h functions */
71 /* ASSUMPTION : int can hold FILE* */
72 static TCHAR _nh_cwd[MAX_PATH];
73 const int MAGIC_OFFSET=5;
74 #define FILE_TABLE_SIZE 256
75 static HANDLE _nh_file_table[FILE_TABLE_SIZE];
76 static int file_pointer = -1;
77
get_file_handle(int i)78 static HANDLE get_file_handle(int i)
79 {
80 i -= MAGIC_OFFSET;
81 if( i>=0 && i<FILE_TABLE_SIZE )
82 return _nh_file_table[i];
83 else
84 return INVALID_HANDLE_VALUE;
85 }
86
alloc_file_handle(HANDLE h)87 static int alloc_file_handle(HANDLE h)
88 {
89 int i;
90 if( file_pointer==-1 ) {
91 file_pointer=0;
92 for(i=0; i<FILE_TABLE_SIZE; i++ )
93 _nh_file_table[i] = INVALID_HANDLE_VALUE;
94 }
95
96 i = (file_pointer+1)%FILE_TABLE_SIZE;
97 while(_nh_file_table[i]!=INVALID_HANDLE_VALUE ) {
98 if( i==file_pointer ) {
99 MessageBox(NULL, _T("Ran out of file handles."), _T("Fatal Error"), MB_OK);
100 abort();
101 }
102 i = (i+1) % FILE_TABLE_SIZE;
103 }
104
105 file_pointer = i;
106 _nh_file_table[file_pointer] = h;
107 return file_pointer+MAGIC_OFFSET;
108 }
109
close(int f)110 int __cdecl close(int f) {
111 int retval;
112 f -= MAGIC_OFFSET;
113 if( f<0 || f>=FILE_TABLE_SIZE ) return -1;
114 retval = (CloseHandle(_nh_file_table[f])? 0 : -1);
115 _nh_file_table[f] = INVALID_HANDLE_VALUE;
116 return retval;
117 }
118
creat(const char * fname,int mode)119 int __cdecl creat(const char *fname , int mode)
120 {
121 HANDLE f;
122 TCHAR wbuf[MAX_PATH+1];
123 ZeroMemory(wbuf, sizeof(wbuf));
124 NH_A2W(fname, wbuf, MAX_PATH);
125
126 f = CreateFile(
127 wbuf,
128 GENERIC_READ | GENERIC_WRITE,
129 0,
130 NULL,
131 CREATE_ALWAYS,
132 FILE_ATTRIBUTE_NORMAL,
133 NULL);
134
135 if( f==INVALID_HANDLE_VALUE ) return -1;
136 else return alloc_file_handle(f);
137 }
138
eof(int f)139 int __cdecl eof(int f)
140 {
141 DWORD fpos, fsize;
142 HANDLE p = get_file_handle(f);
143
144 if( f==-1 ) return -1;
145
146 fpos = SetFilePointer(p, 0, NULL, FILE_CURRENT);
147 fsize = SetFilePointer(p, 0, NULL, FILE_END);
148 if( fpos==0xFFFFFFFF || fsize==0xFFFFFFFF ) return -1;
149 if( fpos==fsize ) return 1;
150 else {
151 SetFilePointer(p, fpos, NULL, FILE_BEGIN);
152 return 0;
153 }
154 }
155
lseek(int f,long offset,int origin)156 long __cdecl lseek( int f, long offset, int origin )
157 {
158 HANDLE p = get_file_handle(f);
159 DWORD fpos;
160 switch(origin) {
161 case SEEK_SET:
162 fpos = SetFilePointer(p, offset, NULL, FILE_BEGIN);
163 break;
164 case SEEK_CUR:
165 fpos = SetFilePointer(p, offset, NULL, FILE_CURRENT);
166 break;
167 case SEEK_END:
168 fpos = SetFilePointer(p, offset, NULL, FILE_END);
169 break;
170 default:
171 fpos = 0xFFFFFFFF;
172 break;
173 }
174 if( fpos==0xFFFFFFFF ) return -1;
175 else return (long)fpos;
176 }
177
open(const char * filename,int oflag,...)178 int __cdecl open( const char *filename, int oflag, ... )
179 {
180 TCHAR fname[MAX_PATH+1];
181 TCHAR path[MAX_PATH+1];
182 HANDLE f;
183 DWORD fileaccess;
184 DWORD filecreate;
185
186 /* O_TEXT is not supported */
187
188 /*
189 * decode the access flags
190 */
191 switch( oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR) ) {
192
193 case _O_RDONLY: /* read access */
194 fileaccess = GENERIC_READ;
195 break;
196 case _O_WRONLY: /* write access */
197 fileaccess = GENERIC_READ | GENERIC_WRITE;
198 break;
199 case _O_RDWR: /* read and write access */
200 fileaccess = GENERIC_READ | GENERIC_WRITE;
201 break;
202 default: /* error, bad oflag */
203 return -1;
204 }
205
206 /*
207 * decode open/create method flags
208 */
209 switch ( oflag & (_O_CREAT | _O_EXCL | _O_TRUNC) ) {
210 case 0:
211 case _O_EXCL: // ignore EXCL w/o CREAT
212 filecreate = OPEN_EXISTING;
213 break;
214
215 case _O_CREAT:
216 filecreate = OPEN_ALWAYS;
217 break;
218
219 case _O_CREAT | _O_EXCL:
220 case _O_CREAT | _O_TRUNC | _O_EXCL:
221 filecreate = CREATE_NEW;
222 break;
223
224 case _O_TRUNC:
225 case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
226 filecreate = TRUNCATE_EXISTING;
227 break;
228
229 case _O_CREAT | _O_TRUNC:
230 filecreate = CREATE_ALWAYS;
231 break;
232
233 default:
234 return -1;
235 }
236
237 /* assemple the file name */
238 ZeroMemory(fname, sizeof(fname));
239 ZeroMemory(path, sizeof(path));
240 NH_A2W(filename, fname, MAX_PATH);
241 if( *filename!='\\' && *filename!='/' ) {
242 _tcscpy(path, _nh_cwd);
243 _tcsncat(path, _T("\\"), MAX_PATH - _tcslen(path));
244 }
245 _tcsncat(path, fname, MAX_PATH - _tcslen(path));
246
247 /*
248 * try to open/create the file
249 */
250 if ( (f = CreateFile( path,
251 fileaccess,
252 0,
253 NULL,
254 filecreate,
255 FILE_ATTRIBUTE_NORMAL,
256 NULL ))
257 == INVALID_HANDLE_VALUE )
258 {
259 return -1;
260 }
261
262 if( !(oflag & O_APPEND) ) SetFilePointer(f, 0, NULL, FILE_BEGIN);
263 return alloc_file_handle(f);
264 }
265
read(int f,void * buffer,unsigned int count)266 int __cdecl read( int f, void *buffer, unsigned int count )
267 {
268 HANDLE p = get_file_handle(f);
269 DWORD bytes_read;
270 if( !ReadFile(p, buffer, count, &bytes_read, NULL) )
271 return -1;
272 else
273 return (int)bytes_read;
274 }
275
unlink(const char * filename)276 int __cdecl unlink(const char * filename)
277 {
278 TCHAR wbuf[MAX_PATH+1];
279 TCHAR fname[MAX_PATH+1];
280
281 ZeroMemory(wbuf, sizeof(wbuf));
282 ZeroMemory(fname, sizeof(fname));
283 NH_A2W(filename, wbuf, MAX_PATH);
284 if( *filename!='\\' && *filename!='/' ) {
285 _tcscpy(fname, _nh_cwd);
286 _tcsncat(fname, _T("\\"), MAX_PATH - _tcslen(fname));
287 }
288 _tcsncat(fname, wbuf, MAX_PATH - _tcslen(fname));
289
290 return !DeleteFileW(fname);
291 }
292
write(int f,const void * buffer,unsigned int count)293 int __cdecl write( int f, const void *buffer, unsigned int count )
294 {
295 HANDLE p = get_file_handle(f);
296 DWORD bytes_written;
297 if( !WriteFile(p, buffer, count, &bytes_written, NULL) )
298 return -1;
299 else
300 return (int)bytes_written;
301 }
302
rename(const char * oldname,const char * newname)303 int __cdecl rename( const char *oldname, const char *newname )
304 {
305 WCHAR f1[MAX_PATH+1];
306 WCHAR f2[MAX_PATH+1];
307 ZeroMemory(f1, sizeof(f1));
308 ZeroMemory(f2, sizeof(f2));
309 MultiByteToWideChar(CP_ACP, 0, oldname, -1, f1, MAX_PATH);
310 MultiByteToWideChar(CP_ACP, 0, newname, -1, f2, MAX_PATH);
311 return !MoveFile(f1, f2);
312 }
313
access(const char * path,int mode)314 int __cdecl access( const char *path, int mode )
315 {
316 DWORD attr;
317 WCHAR f[MAX_PATH+1];
318 ZeroMemory(f, sizeof(f));
319 MultiByteToWideChar(CP_ACP, 0, path, -1, f, MAX_PATH);
320
321 attr = GetFileAttributes(f);
322 if( attr == (DWORD)-1 ) return -1;
323
324 if ( (attr & FILE_ATTRIBUTE_READONLY) && (mode & 2) )
325 return -1;
326 else
327 return 0;
328 }
329
chdir(const char * dirname)330 int chdir( const char *dirname )
331 {
332 ZeroMemory(_nh_cwd, sizeof(_nh_cwd));
333 NH_A2W(dirname, _nh_cwd, MAX_PATH);
334 return 0;
335 }
336
getcwd(char * buffer,int maxlen)337 char *getcwd( char *buffer, int maxlen )
338 {
339 if( maxlen<(int)_tcslen(_nh_cwd) ) return NULL;
340 else return NH_W2A(_nh_cwd, buffer, maxlen);
341 }
342
343 /*------------------------------------------------------------------------------*/
344 /* __errno.h__ */
345 int errno;
346
347 /*------------------------------------------------------------------------------*/
348 /*
349 * Chdrive() changes the default drive.
350 */
351 void
chdrive(char * str)352 chdrive(char *str)
353 {
354 return;
355 }
356
357 /*
358 * This is used in nhlan.c to implement some of the LAN_FEATURES.
359 */
get_username(lan_username_size)360 char *get_username(lan_username_size)
361 int *lan_username_size;
362 {
363 static char username_buffer[BUFSZ];
364 strcpy(username_buffer, "nhsave");
365 return username_buffer;
366 }
367
Delay(int ms)368 void Delay(int ms)
369 {
370 (void)Sleep(ms);
371 }
372
more()373 void more()
374 {
375
376 }
377
isatty(int f)378 int isatty(int f)
379 {
380 return 0;
381 }
382
383
384 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
isupper(int c)385 int __cdecl isupper(int c)
386 {
387 char str[2];
388 WCHAR wstr[2];
389 str[0] = c;
390 str[1] = 0;
391
392 NH_A2W(str, wstr, 1);
393 return iswupper(wstr[0]);
394 }
395
isdigit(int c)396 int __cdecl isdigit(int c)
397 {
398 return ('0' <= c && c <= '9');
399 }
400
isxdigit(int c)401 int __cdecl isxdigit(int c)
402 {
403 return (('0' <= c && c <= '9') ||
404 ('a' <= c && c <= 'f') ||
405 ('A' <= c && c <= 'F'));
406 }
407
isspace(int c)408 int __cdecl isspace(int c)
409 {
410 char str[2];
411 WCHAR wstr[2];
412 str[0] = c;
413 str[1] = 0;
414
415 NH_A2W(str, wstr, 1);
416 return iswspace(wstr[0]);
417 }
418
isprint(int c)419 int __cdecl isprint(int c)
420 {
421 char str[2];
422 WCHAR wstr[2];
423 str[0] = c;
424 str[1] = 0;
425
426 NH_A2W(str, wstr, 1);
427 return iswprint(wstr[0]);
428 }
429
_strdup(const char * s)430 char* __cdecl _strdup(const char* s)
431 {
432 char* p;
433 p = malloc(strlen(s)+1);
434 return strcpy(p, s);
435 }
436
strrchr(const char * s,int c)437 char* __cdecl strrchr( const char *s, int c )
438 {
439 WCHAR wstr[1024];
440 WCHAR *w;
441 w = wcsrchr(NH_A2W(s, wstr, 1024), c);
442 if(w) return (char*)(s + (w - wstr));
443 else return NULL;
444 }
445
_stricmp(const char * a,const char * b)446 int __cdecl _stricmp(const char* a, const char* b)
447 {
448 return strncmpi(a, b, 65535u);
449 }
450
451 #endif
452
453 #if defined(WIN_CE_PS2xx)
454 /* stdio.h functions are missing from PAlm Size PC SDK 1.2 (SH3 and MIPS) */
455
456 #pragma warning(disable:4273)
457
fopen(const char * filename,const char * mode)458 FILE * __cdecl fopen(const char* filename, const char *mode)
459 {
460 int modeflag;
461 int whileflag;
462 int filedes;
463
464 /* First mode character must be 'r', 'w', or 'a'. */
465 switch (*mode) {
466 case 'r':
467 modeflag = _O_RDONLY;
468 break;
469 case 'w':
470 modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
471 break;
472 case 'a':
473 modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
474 break;
475 default:
476 return NULL;
477 }
478
479 whileflag=1;
480 while(*++mode && whileflag)
481 switch(*mode) {
482
483 case '+':
484 if (modeflag & _O_RDWR)
485 whileflag=0;
486 else {
487 modeflag |= _O_RDWR;
488 modeflag &= ~(_O_RDONLY | _O_WRONLY);
489 }
490 break;
491
492 case 'b':
493 if (modeflag & (_O_TEXT | _O_BINARY))
494 whileflag=0;
495 else
496 modeflag |= _O_BINARY;
497 break;
498
499 case 't': /* not supported */
500 whileflag=0;
501 break;
502
503 default:
504 whileflag=0;
505 break;
506 }
507
508 if ((filedes = open(filename, modeflag))==-1) return NULL;
509
510 return (FILE*)filedes;
511 }
512
fscanf(FILE * f,const char * format,...)513 int __cdecl fscanf(FILE *f , const char *format, ...)
514 {
515 /* Format spec: %[*] [width] [l] type ] */
516 int ch;
517 int sch;
518 int matched = 0;
519 int width = 65535;
520 int modifier = -1;
521 int skip_flag = 0;
522 int n_read = 0;
523 char buf[BUFSZ];
524 TCHAR wbuf[BUFSZ];
525 char* p;
526 va_list args;
527
528 #define RETURN_SCANF(i) { va_end(args); return i; }
529 #define NEXT_CHAR(f) (n_read++, fgetc(f))
530
531 va_start(args, format);
532
533 ch = *format++;
534 sch = NEXT_CHAR(f);
535 while( ch && sch!=EOF ) {
536 if( isspace(ch) ) {
537 while( ch && isspace(ch) ) ch = *format++;
538 while( sch!=EOF && isspace(sch) ) sch = NEXT_CHAR(f);
539 format--;
540 goto next_spec;
541 }
542
543 /* read % */
544 if( ch!='%' ) {
545 if( sch!=ch ) RETURN_SCANF(matched);
546 sch = NEXT_CHAR(f);
547 goto next_spec;
548 } else {
549 /* process '%%' */
550 ch = *format++;
551 if( ch=='%' ) {
552 if( sch!='%' ) RETURN_SCANF(matched);
553 sch = NEXT_CHAR(f);
554 goto next_spec;
555 }
556
557 if( ch=='*' ) {
558 /* read skip flag - '*' */
559 skip_flag=1;
560 ch = *format++;
561 }
562
563 /* get width */
564 if( isdigit(ch) ) {
565 width = 0;
566 while(ch && isdigit(ch)) {
567 width = width*10 + (ch-'0');
568 ch = *format++;
569 }
570 }
571
572 /* get modifier */
573 if( ch=='l' ) {
574 modifier = 'l';
575 ch = *format++;
576 }
577
578 /* get type */
579 switch(ch) {
580 case 'c':
581 if( !skip_flag ) {
582 *(va_arg(args, char*))=sch;
583 matched++;
584 }
585 sch = NEXT_CHAR(f);
586 goto next_spec;
587 case 'd':
588 p = buf;
589 /* skip space */
590 while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
591 while(sch!=EOF && isdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
592 *p = '\x0';
593 if( !skip_flag ) {
594 matched++;
595 if( modifier=='l' ) {
596 *(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
597 } else {
598 *(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
599 }
600 }
601 goto next_spec;
602 case 'x':
603 p = buf;
604 while(sch!=EOF && isspace(sch)) sch=NEXT_CHAR(f);
605 while(sch!=EOF && isxdigit(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
606 *p = '\x0';
607 if( !skip_flag ) {
608 matched++;
609 if( modifier=='l' ) {
610 *(va_arg(args, long*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
611 } else {
612 *(va_arg(args, int*))=wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
613 }
614 }
615 goto next_spec;
616 case 'n':
617 *(va_arg(args, int*)) = n_read;
618 matched++;
619 goto next_spec;
620 case 's':
621 if( skip_flag ) {
622 while(sch!=EOF && !isspace(sch) && --width>=0) { sch=NEXT_CHAR(f); }
623 } else {
624 p = va_arg(args, char*);
625 while(sch!=EOF && !isspace(sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
626 *p = '\x0';
627 matched++;
628 }
629 goto next_spec;
630 case '[': {
631 char pattern[256];
632 int start, end;
633 int negate;
634
635 ZeroMemory(pattern, sizeof(pattern));
636 p = pattern;
637
638 /* try to parse '^' modifier */
639 ch = *format++;
640 if( ch=='^' ) { negate=1; ch=*format++; }
641 else { negate=0; }
642 if( ch==0 ) RETURN_SCANF(EOF);
643
644 for( ; ch && ch!=']'; ch = *format++ ) {
645 /* try to parse range: a-z */
646 if( format[0]=='-' &&
647 format[1] && format[1]!=']' ) {
648 start = ch;
649 format++;
650 end = *format++;
651 while(start<=end) {
652 if(!strchr(pattern, (char)start))
653 *p++ = (char)start;
654 start++;
655 }
656 } else {
657 if(!strchr(pattern, (char)ch)) *p++ = (char)ch;
658 }
659 }
660
661 if( skip_flag ) {
662 while(sch!=EOF && strchr(pattern, sch) && --width>=0) { sch=NEXT_CHAR(f); }
663 } else {
664 p = va_arg(args, char*);
665 if( negate )
666 while(sch!=EOF && !strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
667 else
668 while(sch!=EOF && strchr(pattern, sch) && --width>=0) { *p++ = sch; sch=NEXT_CHAR(f); }
669 *p = '\x0';
670 matched++;
671 }
672 } goto next_spec;
673 default:
674 RETURN_SCANF(EOF);
675 }
676 }
677
678 next_spec:
679 width = 65535;
680 modifier = -1;
681 skip_flag = 0;
682 ch = *format++;
683 }
684 fseek(f, -1, SEEK_CUR);
685 RETURN_SCANF(matched);
686
687 #undef RETURN_SCANF
688 #undef NEXT_CHAR
689 }
690
fprintf(FILE * f,const char * format,...)691 int __cdecl fprintf(FILE *f , const char *format, ...)
692 {
693 int retval;
694 va_list args;
695
696 if( !f || !format ) return 0;
697
698 va_start(args, format);
699 retval = vfprintf(f, format, args);
700 va_end(args);
701
702 return retval;
703 }
704
vfprintf(FILE * f,const char * format,va_list args)705 int __cdecl vfprintf(FILE* f, const char *format, va_list args)
706 {
707 char buf[4096];
708 int retval;
709
710 if( !f || !format ) return 0;
711
712 retval = vsprintf(buf, format, args);
713
714 write((int)f, buf, strlen(buf));
715
716 return retval;
717 }
718
fgetc(FILE * f)719 int __cdecl fgetc(FILE * f)
720 {
721 char c;
722 int fh = (int)f;
723
724 if( !f ) return EOF;
725 if( read(fh, &c, 1)==1 ) return c;
726 else return EOF;
727 }
728
fgets(char * s,int size,FILE * f)729 char * __cdecl fgets(char *s, int size, FILE *f)
730 {
731 /* not the best performance but it will do for now...*/
732 char c;
733 if( !f || !s || size==0 ) return NULL;
734 while( --size>0 ) {
735 if( (c = fgetc(f))==EOF ) return NULL;
736
737 *s++ = c;
738 if( c=='\n' ) break;
739 }
740 *s = '\x0';
741 return s;
742 }
743
printf(const char * format,...)744 int __cdecl printf(const char *format, ...)
745 {
746 int retval;
747 va_list args;
748
749 if( !format ) return 0;
750
751 va_start(args, format);
752 retval = vprintf(format, args);
753 va_end(args);
754
755 return retval;
756 }
757
vprintf(const char * format,va_list args)758 int __cdecl vprintf(const char *format, va_list args)
759 {
760 char buf[4096];
761 int retval;
762
763 retval = vsprintf(buf, format, args);
764 puts(buf);
765 return retval;
766 }
767
768 // int __cdecl putchar(int);
puts(const char * s)769 int __cdecl puts(const char * s)
770 {
771 TCHAR wbuf[4096];
772 NH_A2W(s, wbuf, 4096);
773 MessageBox(NULL, wbuf, _T("stdout"), MB_OK);
774 return 0;
775 }
776
_getstdfilex(int desc)777 FILE* __cdecl _getstdfilex(int desc)
778 {
779 return NULL;
780 }
781
fclose(FILE * f)782 int __cdecl fclose(FILE * f)
783 {
784 if(!f) return EOF;
785 return close((int)f)==-1? EOF : 0;
786 }
787
fread(void * p,size_t size,size_t count,FILE * f)788 size_t __cdecl fread(void *p, size_t size, size_t count, FILE *f)
789 {
790 int read_bytes;
791 if(!f || !p || size==0 || count==0) return 0;
792 read_bytes = read((int)f, p, size*count);
793 return read_bytes>0? (read_bytes/size) : 0;
794 }
795
fwrite(const void * p,size_t size,size_t count,FILE * f)796 size_t __cdecl fwrite(const void *p, size_t size, size_t count, FILE * f)
797 {
798 int write_bytes;
799 if(!f || !p || size==0 || count==0) return 0;
800 write_bytes = write((int)f, p, size*count);
801 return write_bytes>0? write_bytes/size : 0;
802 }
803
fflush(FILE * f)804 int __cdecl fflush(FILE *f)
805 {
806 return 0;
807 }
808
feof(FILE * f)809 int __cdecl feof(FILE *f)
810 {
811 return (f && eof((int)f)==0)? 0 : 1;
812 }
813
fseek(FILE * f,long offset,int from)814 int __cdecl fseek(FILE *f, long offset, int from)
815 {
816 return (f && lseek((int)f, offset, from)>=0)? 0 : 1;
817 }
818
ftell(FILE * f)819 long __cdecl ftell(FILE * f)
820 {
821 return f? lseek((int)f, 0, SEEK_CUR) : -1;
822 }
823
824 #endif
825