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