Move the sources to trunk
[opencv] / apps / Hawk / CVEiCL / EiC / module / stdClib / src / stdio.c
1 /* stdio.c
2  *
3  *      (C) Copyright Dec 19 1998, Edmond J. Breen.
4  *                 ALL RIGHTS RESERVED.
5  * This code may be copied for personal, non-profit use only.
6  *
7  */
8
9 /* This file is broken into 2 parts
10  * the first part defines the interface routines
11  * and the 2nd part adds the interface routine
12  * to EiC's look up tables.
13  */
14
15
16 #ifndef  _USE_POSIX
17 #define  _USE_POSIX
18 #endif
19
20 #ifndef _POSIX_SOURCE
21 #define _POSIX_SOURCE 1
22 #endif
23
24 #ifndef __EXTENSIONS__
25 #define __EXTENSIONS__
26 #endif
27
28 #ifndef _XOPEN_SOURCE
29 #define _XOPEN_SOURCE
30 #endif
31
32
33 #include <stdio.h>
34
35 #if 0
36 #ifdef _IRIX
37 extern FILE *popen(const char *, const char *);
38 extern int pclose(FILE *);
39 #endif
40 #endif
41
42
43 #include <stdlib.h>
44 #include <string.h>
45 #ifndef WIN32
46 #include <unistd.h>
47 #endif
48 #include <limits.h>
49 #include <ctype.h>
50 #include <math.h>
51
52 #include "eic.h"
53 #include "stdliblocal.h"
54
55
56 #ifdef PPCLIB
57 void outbyte(int ch);
58 #endif
59
60
61 /* The following code provides for an open FILE cleanup
62 mechanism.  EiC will call _ffexit, cleaning up all open
63 FILEs which were opened in the side effects being discarded.
64         */
65 static size_t NextFopenEntry = 4;
66
67 static size_t book1[FOPEN_MAX] = {1,2,3};
68 static FILE * book2[FOPEN_MAX];
69
70 size_t fopen_NextEntryNum(void) {
71         return NextFopenEntry;
72 }
73
74 /* We assume that eic_fopen() is always closed by eic_fclose()
75 and eic_popen() is aways closed by eic_pclose() so that book[i]
76 being non-zero implies that the associated FILE is still open.
77 This ignores the possibility that a file opened in interpreted
78 code can be closed in compiled code, but such a situation is
79 ill advised in any event.
80         */
81 void _ffexit(size_t Entry) {
82         int i;
83         for(i = 0; i < FOPEN_MAX; i += 1) {
84           if(book1[i] >= Entry) {
85             fclose(stdin + i);
86             book1[i] = 0;
87             book2[i] = NULL;
88           }
89         }
90         return;
91 }
92
93 /*  INTERFACE FUNCTIONS */
94
95 int charin_(char **buf)
96 {
97     int ch;
98     ch = **buf;
99     *buf += 1;
100     if(!ch)
101         ch = EOF;
102     return ch;
103 }
104
105 int charback_(int ch, char **buf)
106 {
107     *buf -= 1;
108     return ch;
109 }
110
111 int charout_(int c, char **buf)
112 {
113     char *s;
114     s = *buf;
115     *s++ = c;
116     *s = 0;
117     *buf = s;
118     return 1;
119 }
120
121 int _eicUprintf(int (*output)(), void *arg, char *fmt, arg_list ap)
122 {
123     /* copy of _UPRINTF that works with EiC's run time stack.
124      * Orginally developed from James Hendrix's Small C tools.
125      *
126      * (c) Edmond J.Breen (March, 1995).
127      *           ALL RIGHTS RESERVED.
128      *
129      * Purpose: To perform formatted printing to a function.
130      *          It performs a superset of printf type
131      *          operations.
132      *
133      *            _UPRINTF   RECOGNISES:
134      * FLAGS:
135      *         -, +, 0 and #.
136      *    plus ! and |  (see below).
137      *
138      * CONVERSION CHARACTERS:
139      *         d, i, o, x, X, u, c, s,
140      *         f, e, E, g, G, p, n, %
141      *    plus b   (see below).
142      *
143      * LENGTH MODIFIES:
144      *          l, L, and h.
145      *
146      * The WIDTH and or the PRECISION can be set indirectly
147      *  via * as specified by K&R.
148      *
149      *        _UPRINTF EXTRA FEATURES.
150      * NEW FLAGS:
151      *        FLAG     WHAT IT SPECIFIES
152      *         |      Centre justification.
153      *         !      Used with floating point numbers.
154      *                   It specifies, if possible, that the
155      *                   number will be centred with respect
156      *                   to the decimal point.
157      *                   If used with non floating point
158      *                   numbers or the floating point number
159      *                   does not contain a decimal point,
160      *                   the ! flag is equivalent to |.
161      * NEW CONVERSION CHARACTER:
162      *      CHARACTER   WHAT IT SPECIFIES
163      *         b      int, unsigned binary notation.
164      */
165   
166     int v;
167
168     static char str[128];
169     char *sptr, lseen,Lseen;
170   
171     int  left, right, centre, maxchr,
172     pad, len, width, sign, dprec,
173     mod, prec,dot,gotfloat;
174   
175     v = 0;
176
177     while(*fmt) {
178         if(*fmt != '%') {
179             (*output)(*fmt,arg);
180             ++fmt;++v;
181             continue;
182         } else if(*++fmt =='%') {
183             (*output)(*fmt++,arg);
184             ++v;
185             continue;
186         }
187         pad = ' ';
188         centre = len = right = left = 0;
189         gotfloat = dot = sign = mod = 0;
190         Lseen = lseen  = dprec = 0;
191         while(*fmt)  {          /* collect in any order */
192             if(*fmt == '-')             left = 1;
193             else if(*fmt == '0')        pad  = '0';
194             else if(*fmt == '+')        sign = 1;
195             else if(*fmt == '#')        mod = 1;
196             else if(*fmt == '|')        centre = 1;
197             else if(*fmt == '!')        centre = 1, dot = 1;
198             else
199                 break;
200             ++fmt;
201         }
202         if(isdigit(*fmt)) {
203             width = atoi(fmt);
204             while(isdigit(*fmt)) ++fmt;
205         } else  if(*fmt == '*') {
206             width = nextarg(ap,int);
207             fmt++;
208         } else
209             width = -1;
210         if(*fmt == '.')  {
211             if(*++fmt == '*')  {
212                 maxchr = nextarg(ap,int);
213                 fmt++;
214             } else {
215                 maxchr = atoi(fmt);
216                 while(isdigit(*fmt)) ++fmt;
217             }
218         } else
219             maxchr = -1;
220     
221         switch(*fmt) {          /* check for length modifier*/
222           case 'h': fmt++;break;
223           case 'l': lseen = 1; fmt++;break;
224           case 'L': Lseen = 1; fmt++;break;
225         }
226         sptr = str;
227         switch(*fmt++) {
228           case 'c': sptr[0] = (char)nextarg(ap,int);
229             sptr[1] = 0;
230             break;
231           case 'b':
232             if(lseen) ultoa(nextarg(ap,long),sptr,2);
233             else utoa(nextarg(ap,int),sptr,2);
234             break;
235           case 'i':
236           case 'd': if(lseen) ltoa(nextarg(ap,long),sptr,10);
237           else itoa(nextarg(ap,int),sptr,10);
238           dprec=1;
239             break;
240           case 'u': if(lseen) ultoa(nextarg(ap,unsigned long),sptr,10);
241           else utoa(nextarg(ap,unsigned),sptr,10);
242           dprec=1;
243             break;
244           case 'o':     if(mod) *sptr = '0';
245             if(lseen)ltoa(nextarg(ap,long),&sptr[mod],8);
246             else itoa(nextarg(ap,int),&sptr[mod],8);
247             dprec = 1;
248             break;
249           case 's': sptr = nextarg(ap,ptr_t).p; break;
250           case 'x': case 'X':
251             if(mod) {
252                 *sptr = '0', sptr[1] = *(fmt-1);
253                 mod++;
254             }
255             if(lseen)ultoa(nextarg(ap,long),&sptr[mod],16);
256             else utoa(nextarg(ap,int),&sptr[mod],16);
257             if(*(fmt-1) == 'X') {
258                 while(*sptr) {
259                     *sptr = toupper(*sptr);
260                     sptr++;
261                 }
262                 sptr = str;
263             }
264             dprec = 1;
265             break;
266             
267           case 'e': case 'E': case 'g': case 'G':
268           case 'f': {
269               int trunc = 0;
270               char type = *(fmt-1),c;
271               double d;
272       
273               gotfloat = 1;
274               if(maxchr < 0) prec = 6;
275               else prec = maxchr,maxchr = -1;
276
277               if(Lseen)
278                   d = nextarg(ap,double);
279               else
280                  d = nextarg(ap,double);
281       
282               if(type == 'g' || type == 'G') {
283                   double ex;
284                   if(d !=0)
285                       ex = log10(d < 0? -d:d);
286                   else
287                       ex = 1;
288                   if(ex < -4 || ex >= prec)
289                       c = type - 2;
290                   else
291                       c = 'f';
292                   trunc = 1;
293               } else
294                   c = type;
295               if(mod) {
296                   if(!prec) prec = 1;
297                   trunc = 0;
298               }
299               sptr = fftoa(d,str, prec, c,trunc);
300           }
301             break;
302           case 'n': *(int*)nextarg(ap,ptr_t).p = v; continue;
303           case 'p':
304               ultoa((long)nextarg(ap,ptr_t).p,sptr,16);
305             break;
306           default: (*output)(*(fmt-1),arg);
307             while(*fmt) {
308                 (*output)(*fmt++,arg);
309                 ++v;
310             }
311             return v;
312         }
313
314         
315         if(!len && sptr) len = strlen(sptr);
316         if(sign) len += (*sptr == '-' ? 0: 1);
317
318         if(dprec && maxchr >=0) {
319             dprec = maxchr;
320             pad = '0';
321             
322         }else
323             dprec = 0;
324             
325         
326         if(maxchr > -1 && maxchr<len)
327             len = maxchr;
328         if(width>len)
329             width = width -len;
330         else if(dprec > len)
331             width = dprec - len;
332         else
333             width = 0;
334     
335         if(centre) {
336             left = (right = width >> 1) + (width%2);
337             if(dot && gotfloat) {
338                 int d = 0,c;
339                 while(sptr[d] && sptr[d] != '.')
340                     d++;
341                 if(sptr[d] == '.') {
342                     c = (width + len)/2;
343                     if(sign && sptr[0] != '-')
344                         d++;
345                     if(c-d > 0) right = c-d;
346                     else right = 0;
347                     if(width - right > 0)
348                         left = width - right;
349                     else
350                         left = 0;
351                 }
352             }
353         } else 
354             if(!left)
355                 right = width;
356             else
357                 left = width;
358     
359         if(sign && !left && pad == '0') {
360             if(*sptr != '-') {
361                 (*output)('+',arg);
362                 ++v;len--;
363             }
364             sign = 0;
365         }
366         while(right--) {(*output)(pad,arg); ++v;}
367         if(sign && *sptr != '-') {(*output)('+',arg);len--;++v;}
368         while(len--) {(*output)(*sptr++,arg);++v;}
369         while(left--) {(*output)(pad,arg);++v;}
370     }
371     return v;
372 }
373
374
375
376 int _eicUscanf(int (*input)(), int (*uget)(),
377             void *arg, const char *fmt, arg_list ap)
378 {
379     /*_USCANF
380      *
381      * (C) May 10 1995 Edmond J.Breen.
382      *           ALL RIGHTS RESERVED.
383      *
384      * Purpose: To perform formatted reading from a function.
385      *          _Uscanf performs a superset of scanf type
386      *          operations.
387      *
388      *            _USCANF   RECOGNISES:
389      *    
390      *     %[*] [width] [h|l|L] [b|d|i|o|x|X|u|c|s|f|e|E|g|G|p|n|%] 
391      *     %[*] [width] [scan-set]
392      *
393      * CONVERSION CHARACTERS:
394      *         d, i, o, x, X, u, c, s
395      *         f, e, E, g, G, p, n, %
396      *    plus b   (see below).
397      *
398      * LENGTH MODIFIES:
399      *          l, L, and h.
400      *
401      *     *    optional assignment-suppression character
402      * WIDTH    optional integer width of field specifier
403      *
404      * SCAN-SET
405      *      [...]   matches the longest non-emtpy string
406      *              of input from the set between the brackects.
407      *      [^...]  matches the longest non-emtpy string
408      *              of input NOT from the set between the brackects.
409      *      []...] and [^]...]
410      *                  includes ] as part of the scan-set.
411      *
412      * NEW CONVERSION CHARACTER:
413      *      CHARACTER   WHAT IT SPECIFIES
414      *         b      int, unsigned binary notation.
415      *
416      * STANDARD C AUXILIARY FUNCTIONS REQUIRED 
417      *    strtol, strtod, strtoul
418      *
419      * LIMITATIONS:
420      *       (1) long double handled as double
421      *       (2) error checking could be improved
422      */
423
424     static char field[256], *p;
425     
426     char *carg, sbuf;
427     int type;
428     int  wast, width,cwidth, ch,  base,cnt;
429     void *vptr;
430     int v;
431
432     
433     cnt = v = 0;
434     
435     while(*fmt != '\0') {
436         if(isspace(*fmt)) {  /* match white space */
437             while(*fmt && isspace(*fmt)) ++fmt;
438             if(*fmt) {
439                 while(isspace((ch=(*input)(arg))))
440                     ++cnt;
441                 (*uget)(ch,arg);
442             }
443             continue;
444         }
445         if(*fmt != '%') { /* match literal text */
446             while(*fmt && !isspace(*fmt) && *fmt != '%')
447                 if((ch=(*input)(arg)) == *fmt) 
448                     ++fmt,++cnt;
449                 else
450                     return v;
451             continue;
452         }
453             
454         if(*++fmt == '*') {
455             vptr = &sbuf;
456             wast = 1;
457             ++fmt;
458         } else if(*fmt == '%') {
459             cnt++;
460             fmt++;
461             continue;
462         } else  {
463             wast = 0;
464             vptr = nextarg(ap,ptr_t).p;
465         }
466
467         for(width = 0;isdigit(*fmt);fmt++)
468             width = *fmt - '0' + width * 10;
469         if(!width)
470             width = INT_MAX, cwidth = 1;
471         else
472             cwidth = width;
473
474         if(*fmt != 'c' && *fmt != '[' && *fmt != 'n') {
475             /* strip leading white space */
476             while(isspace(ch = (*input)(arg)))
477                 ++cnt;
478             if(ch == EOF) {
479                 if(v)
480                     break;
481                 else
482                     return EOF;
483             }
484             (*uget)(ch,arg);
485         }
486
487         
488         switch(*fmt) {
489           case 'h': type = 'h'; ++fmt; break;
490           case 'l': type = 'l'; ++fmt; break;
491           case 'L': type = 'L'; ++fmt; break;
492           default:  type = 0;
493         }
494             
495         switch(*fmt) {
496           case 'c': carg = vptr;
497             while(cwidth--) {
498                 *carg = (*input)(arg);
499                 ++cnt;
500                 if(carg != &sbuf)
501                     ++carg;
502             }
503             break;
504           case 's':
505             carg = vptr;
506             while(width--) {
507                 if((*carg = (*input)(arg)) == EOF)
508                     break;
509                 ++cnt;
510                 if(isspace(*carg)) {
511                     (*uget)(*carg,arg);
512                     --cnt;
513                     break;
514                 } if(carg != &sbuf)
515                     ++carg;
516             }
517             *carg = '\0';
518             break;
519           case '[':
520             ++fmt;
521             
522             if(*fmt == '^') {++fmt; type = 0;}
523             else type = 1;
524             
525             p = (char*)fmt;
526             if(*p == ']') ++p;
527             
528             while(*p && *p != ']') ++p;
529             cwidth = p - fmt;
530             if(cwidth == 0) return EOF;
531             carg = vptr;
532             while((ch = (*input)(arg)) != EOF) 
533                 if(type) {
534                     if(memchr(fmt,ch,cwidth)) {
535                         if(!wast)
536                             *carg++ = ch;
537                         ++cnt;
538                     }else {
539                         (*uget)(ch,arg);
540                         break;
541                     }
542                 } else 
543                     if(!memchr(fmt,ch,cwidth)) {
544                         if(!wast)
545                             *carg++ = ch;
546                         ++cnt;
547                     }else {
548                         (*uget)(ch,arg);
549                         break;
550                     }
551             *carg = '\0';
552             fmt += cwidth;
553             break;          
554           case 'e': case 'f': case 'g':
555           case 'E': case 'G':
556             p = field;
557             ch = (*input)(arg);
558             if(ch == '-' || ch == '+') {
559                 ++cnt;
560                 *p++ = ch;
561             } else
562                 (*uget)(ch,arg);
563             while(width-- && isdigit(ch=(*input)(arg))) {
564                 ++cnt; *p++ = ch;
565             }
566             if(ch == '.' && width-- > 0) {
567                 *p++ = '.';
568                 ++cnt;
569                 while(isdigit(ch=(*input)(arg)) && width--) {
570                     ++cnt;
571                     *p++ = ch;
572                 }
573             }
574             if((ch == 'e' || ch == 'E') && width--) {
575                 *p++ = ch;
576                 ch = (*input)(arg);
577                 if(ch != '+' && ch != '-' && !isdigit(ch) &&
578                    ch != EOF && !isspace(ch)) {
579                     (*uget)(ch,arg);
580                     ch = *--p;
581                 } else
582                     cnt++;
583                     
584             }
585             if((ch == '+' || ch == '-') && width--) {
586                 *p++ = ch;
587                 ++cnt;
588                 ch = (*input)(arg);
589             }           
590             while(isdigit(ch) && width--) {
591                 *p++ = ch;
592                 ++cnt;
593                 ch = (*input)(arg);
594             }
595             (*uget)(ch,arg);
596             if(p == field)
597                 return v;
598             *p = '\0';
599             if(!wast){
600                 double d = strtod(field,NULL);
601                 if(!type || type == 'h')
602                     *(float*)vptr = (float)d;
603                 else if(type == 'l' || type == 'L')
604                     *(double*)vptr = d;
605             }
606             break;
607           case 'n':
608             if(type == 'l')
609                 *(long*)vptr = cnt;
610             else if(type == 'h')
611                 *(short*)vptr = cnt;
612             else
613                 *(int*)vptr = cnt;
614             v--;
615             break;          
616           default:
617             switch(*fmt) {
618             case 'b': base = 2; break;
619             case 'i':
620             case 'd':
621             case 'u':
622                 ch = (*input)(arg);
623                 if(ch == '0') base = 8;
624                 else  base = 10;
625
626                 (*uget)(ch,arg);
627                 break;
628             case 'o': base = 8;  break;
629             case 'x':
630             case 'X': 
631             case 'p': base = 16; break;
632             default:
633                 return v;
634             }
635             p = field;
636             while(width-- && !isspace(ch=(*input)(arg)) && ch != EOF) {
637                 *p++ = ch;
638                 ++cnt;
639             }
640             if(width > 0)
641                 (*uget)(ch,arg);        
642             if(wast)
643                 break;
644             if(p == field)
645                 return v;
646             *p = '\0';
647         {
648             char *endptr;
649             if(*fmt == 'd' || *fmt == 'i') { /* signed conversion */
650                 long lval = strtol(field,&endptr,base);
651                 if(type) {
652                     if(type == 'h')
653                         *(short *)vptr =(short) lval;
654                     else 
655                         *(long *)vptr = lval;
656                 } else
657                     *(int *)vptr = (int) lval;
658                         
659             } else {
660                 unsigned long ulval = strtoul(field,&endptr,base);
661                 if(type) {
662                     if(type == 'h')
663                         *(unsigned short *)vptr =(unsigned short) ulval;
664                     else
665                         *(unsigned long *)vptr = ulval;
666                 } else
667                     *(unsigned *)vptr = (unsigned)ulval;
668             }
669             if(endptr == field) /* failed */
670                 return v;
671             while(--p >= endptr)
672                 (*uget)(*p,arg);
673         }
674             break;
675         }
676         ++fmt;
677         ++v;
678     }
679     return v;
680 }
681
682 #ifndef NO_PIPE
683 val_t eic_popen()
684 {
685     val_t v;
686     arg_list ap = getargs();
687
688 #ifdef WIN32
689     v.p.sp = v.p.p = _popen(arg(0,ap,ptr_t).p,arg(1,ap,ptr_t).p);
690 #else
691     v.p.sp = v.p.p = popen(arg(0,ap,ptr_t).p,arg(1,ap,ptr_t).p);
692 #endif
693
694     if((FILE *)(v.p.p) != NULL) {
695       int i;
696       for(i=1;i<FOPEN_MAX;i++)
697         if(book1[i] == 0)
698           break;
699       book1[i] = NextFopenEntry++;
700       book2[i] = (FILE *)(v.p.p);
701     }
702     setEp( v.p, sizeof(FILE) );
703     
704     return  v;
705 }
706 val_t eic_pclose()
707 {
708   FILE *ptr;
709   val_t v;
710   int i;
711
712   arg_list ap = getargs();
713   
714   ptr = arg(0,ap,ptr_t).p;
715
716 #ifdef WIN32
717   v.ival = _pclose(ptr);
718 #else
719   v.ival = pclose(ptr);
720 #endif
721   
722   for(i=0;i<FOPEN_MAX;i++)
723     if(ptr == book2[i])
724       break;
725   if(i<FOPEN_MAX) {
726     book1[i] = 0;
727     book2[i] = NULL;
728   }
729   return  v;
730 }
731 #endif
732
733
734
735
736 /* STDIO.C STUFF */
737 val_t _get_stdin(void)
738 {
739     val_t v;
740     /*
741      * This function exists so that EiC can get the address stdin.
742      */
743     v.p.sp = v.p.p = stdin;
744     setEp( v.p, sizeof(*stdin) );
745     return v;
746 }
747 val_t _get_stdout(void)
748 {
749     val_t v;
750     /*
751      * This function exists so that EiC can get the address stdout.
752      */
753     v.p.sp = v.p.p = stdout;
754     setEp( v.p, sizeof(*stdout) );
755     return v;
756 }
757 val_t _get_stderr(void)
758 {
759     val_t v;
760     /*
761      * This function exists so that EiC can get the address stderr.
762      */
763     v.p.sp = v.p.p = stderr;
764     setEp( v.p, sizeof(*stderr) );
765     return v;
766 }
767
768
769 #ifndef NO_FSEEK
770 val_t eic_ftell(void)
771 {
772     val_t v;
773     v.lval = ftell(arg(0,getargs(),ptr_t).p);
774     return v;
775 }
776
777 val_t eic_fseek(void)
778 {
779     val_t v;
780     v.ival = fseek(arg(0,getargs(),ptr_t).p,
781                    arg(1,getargs(),long),
782                    arg(2,getargs(),int));
783     return v;
784 }
785 #endif
786
787
788 val_t eic_printf(void)
789 {
790     val_t v;
791     arg_list ap = getargs();
792     char *fmt;
793     
794     fmt = nextarg(ap,ptr_t).p;
795     #ifdef PPCLIB
796     v.ival = _eicUprintf(outbyte,stdout,fmt,ap);
797     #else
798     v.ival = _eicUprintf(fputc,stdout,fmt,ap);
799     #endif
800     return v;
801 }
802
803 val_t eic_fprintf(void)
804 {
805     val_t v;
806     arg_list ap = getargs();
807     FILE *fp;
808     char *fmt;
809     
810     fp = nextarg(ap,ptr_t).p;
811     fmt = nextarg(ap,ptr_t).p;
812     v.ival = _eicUprintf(fputc,fp,fmt,ap);
813     return v;
814 }
815
816 val_t eic_vfprintf(void)
817 {
818     val_t v;
819     arg_list ap = getargs();
820     arg_list ags;
821     FILE *fp;
822     char *fmt;
823     
824     fp = nextarg(ap,ptr_t).p;
825     fmt = nextarg(ap,ptr_t).p;
826     ags = nextarg(ap,arg_list);
827     v.ival = _eicUprintf(fputc,fp,fmt,ags);
828     return v;
829 }
830
831 val_t eic_sprintf(void)
832 {
833     val_t v;
834     arg_list ap = getargs();
835     char *fmt, *str; 
836     str = nextarg(ap,ptr_t).p;
837     fmt = nextarg(ap,ptr_t).p;    
838     v.ival = _eicUprintf(charout_,&str,fmt,ap);
839     return v;
840 }
841
842
843 val_t eic_vsprintf(void)
844 {
845     val_t v;
846     arg_list ap = getargs();
847     arg_list ags;
848     char * str;
849     char *fmt;
850     
851     str = nextarg(ap,ptr_t).p;
852     fmt = nextarg(ap,ptr_t).p;
853     ags = nextarg(ap,arg_list);
854     v.ival = _eicUprintf(charout_,&str,fmt,ags);
855     return v;
856 }
857
858 #ifndef NO_FILEIO
859 val_t eic_freopen(void)
860 {
861     val_t v;
862     arg_list ap = getargs();
863     v.p.sp = v.p.p = freopen(arg(0,ap,ptr_t).p,
864                              arg(1,ap,ptr_t).p,
865                              arg(2,ap,ptr_t).p);
866     
867     setEp( v.p, sizeof(FILE) );
868     return v;
869 }
870
871 val_t eic_fopen(void)
872 {
873     val_t v;
874     arg_list ap = getargs();
875     v.p.sp = v.p.p = fopen(arg(0,ap,ptr_t).p,
876                            arg(1,ap,ptr_t).p);
877     if((FILE *)(v.p.p) != NULL) {
878       int i;
879       for(i=1;i<FOPEN_MAX;i++)
880         if(book1[i] == 0)
881           break;
882       book1[i] = NextFopenEntry++;
883       book2[i] = (FILE *)(v.p.p);
884     }
885     setEp( v.p, sizeof(FILE) );
886     return v;
887 }
888
889 val_t eic_ungetc(void)
890 {
891     val_t v;
892     arg_list ap = getargs();
893     v.ival = ungetc(arg(0,ap,int),
894                     arg(1,ap,ptr_t).p);
895     return v;
896 }
897     
898 val_t eic_fgetc(void)
899 {
900     val_t v;
901     v.ival = fgetc(nextarg(getargs(),ptr_t).p);
902     return v;
903 }
904 val_t eic_fclose(void)
905 {
906   FILE *ptr;
907   val_t v;
908   int i;
909
910   ptr = nextarg(getargs(),ptr_t).p;
911
912   for(i=0;i<FOPEN_MAX;i++)
913     if(ptr == book2[i])
914       break;
915   if(i<FOPEN_MAX) {
916     book1[i] = 0;
917     book2[i] = NULL;
918   }
919
920   v.ival = fclose(ptr);
921   return v;
922 }
923 val_t eic_fflush(void)
924 {
925     val_t v;
926     v.ival = fflush(nextarg(getargs(),ptr_t).p);
927     return v;
928 }
929
930 val_t eic_fputc(void)
931 {
932     val_t v;
933     arg_list ap = getargs();
934     v.ival = fputc(arg(0,ap,int),
935                    arg(1,ap,ptr_t).p);
936     return v;
937 }
938
939 val_t eic_puts(void)
940 {
941     val_t v;
942     arg_list ap = getargs();
943     v.ival = puts(arg(0,ap,ptr_t).p);
944     return v;
945 }
946
947 val_t eic_fputs(void)
948 {
949     val_t v;
950     arg_list ap = getargs();
951     v.ival = fputs(arg(0,ap,ptr_t).p,
952                    arg(1,ap,ptr_t).p);
953     return v;
954 }
955
956 val_t eic_fgets(void)
957 {
958     val_t v;
959     int n;
960     arg_list ap = getargs();
961     getptrarg(0,v.p);
962
963     n = arg(1,ap,int);
964     checkEp(v.p,n);
965
966     v.p.p = fgets(v.p.p,n, arg(2,ap,ptr_t).p);
967     return v;
968 }
969
970 val_t eic_gets(void)
971 {
972     int n;
973     val_t v;
974     getptrarg(0,v.p);
975
976     n = (char*)v.p.ep - (char*)v.p.sp;
977     v.p.p = fgets(v.p.p,n,stdin);
978     return v;
979 }
980
981 val_t eic_fread(void)
982 {
983     val_t v;
984     arg_list ap = getargs();
985     v.szval = fread(arg(0,ap,ptr_t).p,
986                    arg(1,ap,size_t),
987                    arg(2,ap,size_t),
988                    arg(3,ap,ptr_t).p);
989     return v;
990 }
991
992 val_t eic_fwrite(void)
993 {
994     val_t v;
995     arg_list ap;
996     ap = getargs();
997     v.szval = fwrite(arg(0,ap,ptr_t).p,
998                    arg(1,ap,size_t),
999                    arg(2,ap,size_t),
1000                    arg(3,ap,ptr_t).p);
1001     return v;
1002 }
1003
1004 val_t eic_fscanf(void)
1005 {
1006     val_t v;
1007     arg_list ap = getargs();
1008     v.ival = _eicUscanf(fgetc,ungetc,
1009                      arg(0,ap,ptr_t).p,
1010                      arg(1,ap,ptr_t).p,ap-2);
1011     return v;
1012 }
1013
1014 val_t eic_feof(void)
1015 {
1016     val_t v;
1017     getptrarg(0,v.p);
1018     v.ival = feof((FILE *)(v.p.p));
1019     return v;
1020 }
1021
1022 val_t eic_ferror(void)
1023 {
1024     val_t v;
1025     getptrarg(0,v.p);
1026     v.ival = ferror((FILE *)(v.p.p));
1027     return v;
1028 }
1029
1030 val_t eic_rewind(void)
1031 {
1032     val_t v;
1033     getptrarg(0,v.p);
1034     rewind((FILE *)(v.p.p));
1035     return v;
1036 }
1037
1038 val_t eic_fsetpos(void)
1039 {
1040     val_t v;
1041     arg_list ap = getargs();
1042     v.ival = fsetpos(arg(0,ap,ptr_t).p,
1043                    arg(1,ap,ptr_t).p);
1044     return v;
1045 }
1046
1047 val_t eic_fgetpos(void)
1048 {
1049     val_t v;
1050     arg_list ap = getargs();
1051     v.ival = fgetpos(arg(0,ap,ptr_t).p,
1052                    arg(1,ap,ptr_t).p);
1053     return v;
1054 }
1055
1056 #endif
1057
1058 val_t eic_scanf(void)
1059 {
1060     val_t v;
1061     arg_list ap = getargs();
1062     v.ival = _eicUscanf(fgetc,ungetc,
1063                      stdin,
1064                      arg(0,ap,ptr_t).p,ap-1);
1065     return v;
1066 }
1067
1068 val_t eic_sscanf(void)
1069 {
1070     val_t v;
1071     char * str;
1072     arg_list ap = getargs();
1073     str = arg(0,ap,ptr_t).p;
1074     v.ival = _eicUscanf(charin_,charback_,
1075                      &str,
1076                      arg(1,ap,ptr_t).p,ap-2);
1077     return v;
1078 }
1079
1080 val_t eic_setvbuf(void)
1081 {
1082     val_t v;
1083     arg_list ap = getargs();
1084     v.ival = setvbuf(arg(0,ap,ptr_t).p,
1085                      arg(1,ap,ptr_t).p,
1086                      arg(2,ap,int),
1087                      arg(3,ap,size_t));
1088     return v;
1089 }
1090
1091 #ifndef NO_TMPFILE
1092 val_t eic_tmpnam(void)
1093 {
1094     val_t v;
1095     v.p.sp = v.p.p = tmpnam(arg(0,getargs(),ptr_t).p);
1096     setEp( v.p, strlen(v.p.p) + 1 );
1097     return v;
1098 }
1099 val_t eic_tmpfile(void)
1100 {
1101     val_t v;
1102     v.p.sp = v.p.p = tmpfile();
1103     setEp( v.p, strlen(v.p.p) + 1 );
1104     return v;
1105 }
1106
1107 val_t eic_rename(void)
1108 {
1109     val_t v;
1110 #ifdef WIN32
1111     v.ival = rename(arg(0,getargs(),ptr_t).p,
1112                   arg(1,getargs(),ptr_t).p);
1113 #else
1114     v.ival = link(arg(0,getargs(),ptr_t).p,
1115                   arg(1,getargs(),ptr_t).p);
1116     if(v.ival == 0)
1117         v.ival =  unlink(arg(0,getargs(),ptr_t).p);
1118 #endif
1119     return v;
1120 }
1121
1122
1123 val_t eic_clearerr(void)
1124 {
1125     val_t v;
1126     clearerr((FILE *)(arg(0,getargs(),ptr_t).p));
1127     return v;
1128 }
1129
1130 val_t eic_perror(void)
1131 {
1132     val_t v;
1133     perror(arg(0,getargs(),ptr_t).p);
1134     return v;
1135 }
1136 #endif
1137
1138 /**********************************************************************************/
1139
1140 void module_stdio(void)
1141 {
1142
1143     book2[0] = stdin;
1144     book2[1] = stdout;
1145     book2[2] = stderr;
1146
1147     /* stdio.h stuff that were macros */
1148     EiC_add_builtinfunc("puts", eic_puts);
1149     EiC_add_builtinfunc("feof", eic_feof);
1150     EiC_add_builtinfunc("ferror", eic_ferror);
1151     EiC_add_builtinfunc("rewind", eic_rewind);
1152     EiC_add_builtinfunc("fsetpos", eic_fsetpos);
1153     EiC_add_builtinfunc("fgetpos", eic_fgetpos);
1154
1155     /* stdio.h stuff */
1156     EiC_add_builtinfunc("_get_stdin",_get_stdin);
1157     EiC_add_builtinfunc("_get_stdout",_get_stdout);
1158     EiC_add_builtinfunc("_get_stderr",_get_stderr);
1159     EiC_add_builtinfunc("ftell", eic_ftell);
1160     EiC_add_builtinfunc("freopen",eic_freopen); 
1161     EiC_add_builtinfunc("fopen",eic_fopen);     
1162     EiC_add_builtinfunc("printf", eic_printf);
1163     EiC_add_builtinfunc("fprintf", eic_fprintf);
1164     EiC_add_builtinfunc("sprintf", eic_sprintf);
1165     EiC_add_builtinfunc("vfprintf", eic_vfprintf);
1166     EiC_add_builtinfunc("vsprintf", eic_vsprintf);
1167     EiC_add_builtinfunc("ungetc", eic_ungetc);
1168     EiC_add_builtinfunc("fgetc", eic_fgetc);
1169     EiC_add_builtinfunc("fputc", eic_fputc);
1170     EiC_add_builtinfunc("fputs", eic_fputs);
1171     EiC_add_builtinfunc("fgets", eic_fgets);
1172     EiC_add_builtinfunc("gets", eic_gets);
1173     EiC_add_builtinfunc("fread", eic_fread);
1174     EiC_add_builtinfunc("fwrite", eic_fwrite);
1175     EiC_add_builtinfunc("fflush", eic_fflush);
1176     EiC_add_builtinfunc("fclose", eic_fclose);
1177     EiC_add_builtinfunc("fscanf", eic_fscanf);
1178     EiC_add_builtinfunc("sscanf", eic_sscanf);
1179     EiC_add_builtinfunc("scanf", eic_scanf);
1180     EiC_add_builtinfunc("setvbuf", eic_setvbuf);
1181     EiC_add_builtinfunc("tmpnam", eic_tmpnam);
1182     EiC_add_builtinfunc("tmpfile", eic_tmpfile);
1183     EiC_add_builtinfunc("rename",eic_rename);
1184     EiC_add_builtinfunc("fseek", eic_fseek);
1185     EiC_add_builtinfunc("clearerr", eic_clearerr);
1186     EiC_add_builtinfunc("perror", eic_perror);
1187    
1188
1189 #ifndef NO_PIPE
1190     EiC_add_builtinfunc("popen", eic_popen);
1191     EiC_add_builtinfunc("pclose", eic_pclose);
1192 #endif
1193
1194 }
1195