NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / sys / wince / celib.c
blob0abef342112bda48bfba19130c5377d9a402d129
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. */
5 #define NEED_VARARGS
6 #include "hack.h"
7 #include <fcntl.h>
8 // #include "wceconf.h"
10 static union {
11 time_t t_val;
12 struct time_pack {
13 unsigned int ss : 6;
14 unsigned int mm : 6;
15 unsigned int dd : 5;
16 unsigned int hh : 6;
17 unsigned int mo : 4;
18 unsigned int yr : 10;
19 unsigned int wd : 3;
20 } tm_val;
21 } _t_cnv;
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)
30 static struct tm ptm;
31 int i;
32 if (!ptime)
33 return NULL;
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++)
47 ptm.tm_yday +=
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 */
51 return &ptm;
54 time_t __cdecl time(time_t *timeptr)
56 SYSTEMTIME stm;
57 GetLocalTime(&stm);
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;
67 if (timeptr)
68 *timeptr = _t_cnv.t_val;
69 return _t_cnv.t_val;
72 time_t __cdecl mktime(struct tm *tb)
74 if (!tb)
75 return (time_t) -1;
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;
85 return _t_cnv.t_val;
88 /*------------------------------------------------------------------------------*/
89 /* __io.h__ */
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;
98 static HANDLE
99 get_file_handle(int i)
101 i -= MAGIC_OFFSET;
102 if (i >= 0 && i < FILE_TABLE_SIZE)
103 return _nh_file_table[i];
104 else
105 return INVALID_HANDLE_VALUE;
108 static int
109 alloc_file_handle(HANDLE h)
111 int i;
112 if (file_pointer == -1) {
113 file_pointer = 0;
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);
123 abort();
125 i = (i + 1) % FILE_TABLE_SIZE;
128 file_pointer = i;
129 _nh_file_table[file_pointer] = h;
130 return file_pointer + MAGIC_OFFSET;
133 int __cdecl close(int f)
135 int retval;
136 f -= MAGIC_OFFSET;
137 if (f < 0 || f >= FILE_TABLE_SIZE)
138 return -1;
139 retval = (CloseHandle(_nh_file_table[f]) ? 0 : -1);
140 _nh_file_table[f] = INVALID_HANDLE_VALUE;
141 return retval;
144 int __cdecl creat(const char *fname, int mode)
146 HANDLE f;
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)
155 return -1;
156 else
157 return alloc_file_handle(f);
160 int __cdecl eof(int f)
162 DWORD fpos, fsize;
163 HANDLE p = get_file_handle(f);
165 if (f == -1)
166 return -1;
168 fpos = SetFilePointer(p, 0, NULL, FILE_CURRENT);
169 fsize = SetFilePointer(p, 0, NULL, FILE_END);
170 if (fpos == 0xFFFFFFFF || fsize == 0xFFFFFFFF)
171 return -1;
172 if (fpos == fsize)
173 return 1;
174 else {
175 SetFilePointer(p, fpos, NULL, FILE_BEGIN);
176 return 0;
180 long __cdecl lseek(int f, long offset, int origin)
182 HANDLE p = get_file_handle(f);
183 DWORD fpos;
184 switch (origin) {
185 case SEEK_SET:
186 fpos = SetFilePointer(p, offset, NULL, FILE_BEGIN);
187 break;
188 case SEEK_CUR:
189 fpos = SetFilePointer(p, offset, NULL, FILE_CURRENT);
190 break;
191 case SEEK_END:
192 fpos = SetFilePointer(p, offset, NULL, FILE_END);
193 break;
194 default:
195 fpos = 0xFFFFFFFF;
196 break;
198 if (fpos == 0xFFFFFFFF)
199 return -1;
200 else
201 return (long) fpos;
204 int __cdecl open(const char *filename, int oflag, ...)
206 TCHAR fname[MAX_PATH + 1];
207 TCHAR path[MAX_PATH + 1];
208 HANDLE f;
209 DWORD fileaccess;
210 DWORD filecreate;
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;
220 break;
221 case _O_WRONLY: /* write access */
222 fileaccess = GENERIC_READ | GENERIC_WRITE;
223 break;
224 case _O_RDWR: /* read and write access */
225 fileaccess = GENERIC_READ | GENERIC_WRITE;
226 break;
227 default: /* error, bad oflag */
228 return -1;
232 * decode open/create method flags
234 switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
235 case 0:
236 case _O_EXCL: // ignore EXCL w/o CREAT
237 filecreate = OPEN_EXISTING;
238 break;
240 case _O_CREAT:
241 filecreate = OPEN_ALWAYS;
242 break;
244 case _O_CREAT | _O_EXCL:
245 case _O_CREAT | _O_TRUNC | _O_EXCL:
246 filecreate = CREATE_NEW;
247 break;
249 case _O_TRUNC:
250 case _O_TRUNC | _O_EXCL: // ignore EXCL w/o CREAT
251 filecreate = TRUNCATE_EXISTING;
252 break;
254 case _O_CREAT | _O_TRUNC:
255 filecreate = CREATE_ALWAYS;
256 break;
258 default:
259 return -1;
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) {
278 return -1;
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);
289 DWORD bytes_read;
290 if (!ReadFile(p, buffer, count, &bytes_read, NULL))
291 return -1;
292 else
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);
316 DWORD bytes_written;
317 if (!WriteFile(p, buffer, count, &bytes_written, NULL))
318 return -1;
319 else
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)
336 DWORD attr;
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)
343 return -1;
345 if ((attr & FILE_ATTRIBUTE_READONLY) && (mode & 2))
346 return -1;
347 else
348 return 0;
352 chdir(const char *dirname)
354 ZeroMemory(_nh_cwd, sizeof(_nh_cwd));
355 NH_A2W(dirname, _nh_cwd, MAX_PATH);
356 return 0;
359 char *
360 getcwd(char *buffer, int maxlen)
362 if (maxlen < (int) _tcslen(_nh_cwd))
363 return NULL;
364 else
365 return NH_W2A(_nh_cwd, buffer, maxlen);
368 /*------------------------------------------------------------------------------*/
369 /* __errno.h__ */
370 int errno;
372 /*------------------------------------------------------------------------------*/
374 * Chdrive() changes the default drive.
376 void
377 chdrive(char *str)
379 return;
383 * This is used in nhlan.c to implement some of the LAN_FEATURES.
385 char *
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;
394 void
395 Delay(int ms)
397 (void) Sleep(ms);
400 void
401 more()
406 isatty(int f)
408 return 0;
411 #if defined(WIN_CE_PS2xx) || defined(WIN32_PLATFORM_HPCPRO)
412 int __cdecl isupper(int c)
414 char str[2];
415 WCHAR wstr[2];
416 str[0] = c;
417 str[1] = 0;
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)
436 char str[2];
437 WCHAR wstr[2];
438 str[0] = c;
439 str[1] = 0;
441 NH_A2W(str, wstr, 1);
442 return iswspace(wstr[0]);
445 int __cdecl isprint(int c)
447 char str[2];
448 WCHAR wstr[2];
449 str[0] = c;
450 str[1] = 0;
452 NH_A2W(str, wstr, 1);
453 return iswprint(wstr[0]);
456 char *__cdecl _strdup(const char *s)
458 char *p;
459 p = malloc(strlen(s) + 1);
460 return strcpy(p, s);
463 char *__cdecl strrchr(const char *s, int c)
465 WCHAR wstr[1024];
466 WCHAR *w;
467 w = wcsrchr(NH_A2W(s, wstr, 1024), c);
468 if (w)
469 return (char *) (s + (w - wstr));
470 else
471 return NULL;
474 int __cdecl _stricmp(const char *a, const char *b)
476 return strncmpi(a, b, 65535u);
479 #endif
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)
488 int modeflag;
489 int whileflag;
490 int filedes;
492 /* First mode character must be 'r', 'w', or 'a'. */
493 switch (*mode) {
494 case 'r':
495 modeflag = _O_RDONLY;
496 break;
497 case 'w':
498 modeflag = _O_WRONLY | _O_CREAT | _O_TRUNC;
499 break;
500 case 'a':
501 modeflag = _O_WRONLY | _O_CREAT | _O_APPEND;
502 break;
503 default:
504 return NULL;
507 whileflag = 1;
508 while (*++mode && whileflag)
509 switch (*mode) {
510 case '+':
511 if (modeflag & _O_RDWR)
512 whileflag = 0;
513 else {
514 modeflag |= _O_RDWR;
515 modeflag &= ~(_O_RDONLY | _O_WRONLY);
517 break;
519 case 'b':
520 if (modeflag & (_O_TEXT | _O_BINARY))
521 whileflag = 0;
522 else
523 modeflag |= _O_BINARY;
524 break;
526 case 't': /* not supported */
527 whileflag = 0;
528 break;
530 default:
531 whileflag = 0;
532 break;
535 if ((filedes = open(filename, modeflag)) == -1)
536 return NULL;
538 return (FILE *) filedes;
541 int __cdecl fscanf(FILE *f, const char *format, ...)
543 /* Format spec: %[*] [width] [l] type ] */
544 int ch;
545 int sch;
546 int matched = 0;
547 int width = 65535;
548 int modifier = -1;
549 int skip_flag = 0;
550 int n_read = 0;
551 char buf[BUFSZ];
552 TCHAR wbuf[BUFSZ];
553 char *p;
554 va_list args;
556 #define RETURN_SCANF(i) \
558 va_end(args); \
559 return i; \
561 #define NEXT_CHAR(f) (n_read++, fgetc(f))
563 va_start(args, format);
565 ch = *format++;
566 sch = NEXT_CHAR(f);
567 while (ch && sch != EOF) {
568 if (isspace(ch)) {
569 while (ch && isspace(ch))
570 ch = *format++;
571 while (sch != EOF && isspace(sch))
572 sch = NEXT_CHAR(f);
573 format--;
574 goto next_spec;
577 /* read % */
578 if (ch != '%') {
579 if (sch != ch)
580 RETURN_SCANF(matched);
581 sch = NEXT_CHAR(f);
582 goto next_spec;
583 } else {
584 /* process '%%' */
585 ch = *format++;
586 if (ch == '%') {
587 if (sch != '%')
588 RETURN_SCANF(matched);
589 sch = NEXT_CHAR(f);
590 goto next_spec;
593 if (ch == '*') {
594 /* read skip flag - '*' */
595 skip_flag = 1;
596 ch = *format++;
599 /* get width */
600 if (isdigit(ch)) {
601 width = 0;
602 while (ch && isdigit(ch)) {
603 width = width * 10 + (ch - '0');
604 ch = *format++;
608 /* get modifier */
609 if (ch == 'l') {
610 modifier = 'l';
611 ch = *format++;
614 /* get type */
615 switch (ch) {
616 case 'c':
617 if (!skip_flag) {
618 *(va_arg(args, char *) ) = sch;
619 matched++;
621 sch = NEXT_CHAR(f);
622 goto next_spec;
623 case 'd':
624 p = buf;
625 /* skip space */
626 while (sch != EOF && isspace(sch))
627 sch = NEXT_CHAR(f);
628 while (sch != EOF && isdigit(sch) && --width >= 0) {
629 *p++ = sch;
630 sch = NEXT_CHAR(f);
632 *p = '\x0';
633 if (!skip_flag) {
634 matched++;
635 if (modifier == 'l') {
636 *(va_arg(args, long *) ) =
637 wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
638 } else {
639 *(va_arg(args, int *) ) =
640 wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
643 goto next_spec;
644 case 'x':
645 p = buf;
646 while (sch != EOF && isspace(sch))
647 sch = NEXT_CHAR(f);
648 while (sch != EOF && isxdigit(sch) && --width >= 0) {
649 *p++ = sch;
650 sch = NEXT_CHAR(f);
652 *p = '\x0';
653 if (!skip_flag) {
654 matched++;
655 if (modifier == 'l') {
656 *(va_arg(args, long *) ) =
657 wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
658 } else {
659 *(va_arg(args, int *) ) =
660 wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
663 goto next_spec;
664 case 'n':
665 *(va_arg(args, int *) ) = n_read;
666 matched++;
667 goto next_spec;
668 case 's':
669 if (skip_flag) {
670 while (sch != EOF && !isspace(sch) && --width >= 0) {
671 sch = NEXT_CHAR(f);
673 } else {
674 p = va_arg(args, char *);
675 while (sch != EOF && !isspace(sch) && --width >= 0) {
676 *p++ = sch;
677 sch = NEXT_CHAR(f);
679 *p = '\x0';
680 matched++;
682 goto next_spec;
683 case '[': {
684 char pattern[256];
685 int start, end;
686 int negate;
688 ZeroMemory(pattern, sizeof(pattern));
689 p = pattern;
691 /* try to parse '^' modifier */
692 ch = *format++;
693 if (ch == '^') {
694 negate = 1;
695 ch = *format++;
696 } else {
697 negate = 0;
699 if (ch == 0)
700 RETURN_SCANF(EOF);
702 for (; ch && ch != ']'; ch = *format++) {
703 /* try to parse range: a-z */
704 if (format[0] == '-' && format[1] && format[1] != ']') {
705 start = ch;
706 format++;
707 end = *format++;
708 while (start <= end) {
709 if (!strchr(pattern, (char) start))
710 *p++ = (char) start;
711 start++;
713 } else {
714 if (!strchr(pattern, (char) ch))
715 *p++ = (char) ch;
719 if (skip_flag) {
720 while (sch != EOF && strchr(pattern, sch)
721 && --width >= 0) {
722 sch = NEXT_CHAR(f);
724 } else {
725 p = va_arg(args, char *);
726 if (negate)
727 while (sch != EOF && !strchr(pattern, sch)
728 && --width >= 0) {
729 *p++ = sch;
730 sch = NEXT_CHAR(f);
732 else
733 while (sch != EOF && strchr(pattern, sch)
734 && --width >= 0) {
735 *p++ = sch;
736 sch = NEXT_CHAR(f);
738 *p = '\x0';
739 matched++;
742 goto next_spec;
743 default:
744 RETURN_SCANF(EOF);
748 next_spec:
749 width = 65535;
750 modifier = -1;
751 skip_flag = 0;
752 ch = *format++;
754 fseek(f, -1, SEEK_CUR);
755 RETURN_SCANF(matched);
757 #undef RETURN_SCANF
758 #undef NEXT_CHAR
761 int __cdecl fprintf(FILE *f, const char *format, ...)
763 int retval;
764 va_list args;
766 if (!f || !format)
767 return 0;
769 va_start(args, format);
770 retval = vfprintf(f, format, args);
771 va_end(args);
773 return retval;
776 int __cdecl vfprintf(FILE *f, const char *format, va_list args)
778 char buf[4096];
779 int retval;
781 if (!f || !format)
782 return 0;
784 retval = vsprintf(buf, format, args);
786 write((int) f, buf, strlen(buf));
788 return retval;
791 int __cdecl fgetc(FILE *f)
793 char c;
794 int fh = (int) f;
796 if (!f)
797 return EOF;
798 if (read(fh, &c, 1) == 1)
799 return c;
800 else
801 return EOF;
804 char *__cdecl fgets(char *s, int size, FILE *f)
806 /* not the best performance but it will do for now...*/
807 char c;
808 if (!f || !s || size == 0)
809 return NULL;
810 while (--size > 0) {
811 if ((c = fgetc(f)) == EOF)
812 return NULL;
814 *s++ = c;
815 if (c == '\n')
816 break;
818 *s = '\x0';
819 return s;
822 int __cdecl printf(const char *format, ...)
824 int retval;
825 va_list args;
827 if (!format)
828 return 0;
830 va_start(args, format);
831 retval = vprintf(format, args);
832 va_end(args);
834 return retval;
837 int __cdecl vprintf(const char *format, va_list args)
839 char buf[4096];
840 int retval;
842 retval = vsprintf(buf, format, args);
843 puts(buf);
844 return retval;
847 // int __cdecl putchar(int);
848 int __cdecl puts(const char *s)
850 TCHAR wbuf[4096];
851 NH_A2W(s, wbuf, 4096);
852 MessageBox(NULL, wbuf, _T("stdout"), MB_OK);
853 return 0;
856 FILE *__cdecl _getstdfilex(int desc)
858 return NULL;
861 int __cdecl fclose(FILE *f)
863 if (!f)
864 return EOF;
865 return close((int) f) == -1 ? EOF : 0;
868 size_t __cdecl fread(void *p, size_t size, size_t count, FILE *f)
870 int read_bytes;
871 if (!f || !p || size == 0 || count == 0)
872 return 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)
879 int write_bytes;
880 if (!f || !p || size == 0 || count == 0)
881 return 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)
888 return 0;
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;
906 #endif