1 /* Copyright (C) by GFD-Dennou Club, 1999-2000. All rights reserved. */
2 #include "sys/types.h"
3 #include "sys/stat.h"
4 #include "libtinyf2c.h"
5
6 #undef abs
7 #undef min
8 #undef max
9 #include "stdlib.h"
10 #include "fio.h"
11 #include "fmt.h" /* for struct syl */
12
13 /*global definitions*/
14 unit f__units[MXUNIT]; /*unit table*/
15 flag f__init; /*0 on entry, 1 after initializations*/
16 cilist *f__elist; /*active external io list*/
17 icilist *f__svic; /*active internal io list*/
18 flag f__reading; /*1 if reading, 0 if writing*/
19 flag f__cplus,f__cblank;
20 char *f__fmtbuf; /*format */
21 flag f__external; /*1 if external io, 0 if internal */
22
23 int (*f__getn)(void); /* for formatted input */
24 void (*f__putn)(int); /* for formatted output */
25 int (*f__doed)(struct syl*, char*, ftnlen),(*f__doned)(struct syl*);
26 int (*f__dorevert)(void),(*f__donewrec)(void),(*f__doend)(void);
27
28 flag f__sequential; /*1 if sequential io, 0 if direct*/
29 flag f__formatted; /*1 if formatted io, 0 if unformatted*/
30 FILE *f__cf; /*current file*/
31 unit *f__curunit; /*current unit*/
32 int f__recpos; /*place in current record*/
33 int f__cursor, f__hiwater, f__scale;
34 char *f__icptr;
35
36 /*error messages*/
37 char *F_err[] =
38 {
39 "error in format", /* 100 */
40 "illegal unit number", /* 101 */
41 "formatted io not allowed", /* 102 */
42 "unformatted io not allowed", /* 103 */
43 "direct io not allowed", /* 104 */
44 "sequential io not allowed", /* 105 */
45 "can't backspace file", /* 106 */
46 "null file name", /* 107 */
47 "can't stat file", /* 108 */
48 "unit not connected", /* 109 */
49 "off end of record", /* 110 */
50 "truncation failed in endfile", /* 111 */
51 "incomprehensible list input", /* 112 */
52 "out of free space", /* 113 */
53 "unit not connected", /* 114 */
54 "read unexpected character", /* 115 */
55 "bad logical input field", /* 116 */
56 "bad variable type", /* 117 */
57 "bad namelist name", /* 118 */
58 "variable not in namelist", /* 119 */
59 "no end record", /* 120 */
60 "variable count incorrect", /* 121 */
61 "subscript for scalar variable", /* 122 */
62 "invalid array section", /* 123 */
63 "substring out of bounds", /* 124 */
64 "subscript out of bounds", /* 125 */
65 "can't read file", /* 126 */
66 "can't write file", /* 127 */
67 "'new' file exists", /* 128 */
68 "can't append to file", /* 129 */
69 "non-positive record number" /* 130 */
70 };
71 #define MAXERR (sizeof(F_err)/sizeof(char *)+100)
72
73 /* to check wether the file can be seeked or not
74 */
f__canseek(FILE * f)75 f__canseek(FILE *f) /*SYSDEP*/
76 {
77 struct stat x;
78
79 if (fstat(fileno(f),&x) < 0)
80 return(0);
81 switch(x.st_mode & S_IFMT) {
82 case S_IFDIR:
83 case S_IFREG:
84 if(x.st_nlink > 0) /* !pipe */
85 return(1);
86 else
87 return(0);
88 case S_IFCHR:
89 if(isatty(fileno(f)))
90 return(0);
91 return(1);
92 #ifdef S_IFBLK
93 case S_IFBLK:
94 return(1);
95 #endif
96 }
97 return(0); /* who knows what it is? */
98 }
99
100 /* when there are some serious error occur, we will stop the program
101 */
f__fatal(int n,char * s)102 void f__fatal(int n, char *s)
103 {
104 if(n<100 && n>=0)
105 perror(s); /*SYSDEP*/
106 else if(n >= (int)MAXERR || n < -1)
107 fprintf(stderr,"%s: illegal error number %d\n",s,n);
108 else if(n == -1)
109 fprintf(stderr,"%s: end of file\n",s);
110 else
111 fprintf(stderr,"%s: %s\n",s,F_err[n-100]);
112 if (f__curunit) {
113 fprintf(stderr,"apparent state: unit %d ",
114 (int)(f__curunit-f__units));
115 fprintf(stderr, f__curunit->ufnm ? "named %s\n" : "(unnamed)\n",
116 f__curunit->ufnm);
117 }
118 else
119 fprintf(stderr,"apparent state: internal I/O\n");
120 if (f__fmtbuf)
121 fprintf(stderr,"last format: %s\n",f__fmtbuf);
122 fprintf(stderr,"lately %s %s %s %s",f__reading?"reading":"writing",
123 f__sequential?"sequential":"direct",f__formatted?"formatted":"unformatted",
124 f__external?"external":"internal");
125 sig_die(" IO", 1);
126 }
127
128 /*initialization routine*/
f_init(Void)129 VOID f_init(Void)
130 {
131 unit *p;
132
133 f__init=1;
134 p= &f__units[0];
135 p->ufd=stderr;
136 p->useek=f__canseek(stderr);
137 p->ufmt=1;
138 p->uwrt=1;
139 p = &f__units[5];
140 p->ufd=stdin;
141 p->useek=f__canseek(stdin);
142 p->ufmt=1;
143 p->uwrt=0;
144 p= &f__units[6];
145 p->ufd=stdout;
146 p->useek=f__canseek(stdout);
147 p->ufmt=1;
148 p->uwrt=1;
149 }
150
151 /* check wether the file can be read
152 */
f__nowreading(unit * x)153 f__nowreading(unit *x)
154 {
155 long loc;
156 int ufmt, urw;
157 extern char *f__r_mode[], *f__w_mode[];
158
159 if (x->urw & 1)
160 goto done;
161 if (!x->ufnm)
162 goto cantread;
163 ufmt = x->url ? 0 : x->ufmt;
164 loc = ftell(x->ufd);
165 urw = 3;
166 if (!freopen(x->ufnm, f__w_mode[ufmt|2], x->ufd)) {
167 urw = 1;
168 if(!freopen(x->ufnm, f__r_mode[ufmt], x->ufd)) {
169 cantread:
170 errno = 126;
171 return 1;
172 }
173 }
174 fseek(x->ufd,loc,SEEK_SET);
175 x->urw = urw;
176 done:
177 x->uwrt = 0;
178 return 0;
179 }
180
181 /* check wether the file can be write
182 */
f__nowwriting(unit * x)183 f__nowwriting(unit *x)
184 {
185 long loc;
186 int ufmt;
187 extern char *f__w_mode[];
188
189 if (x->urw & 2)
190 goto done;
191 if (!x->ufnm)
192 goto cantwrite;
193 ufmt = x->url ? 0 : x->ufmt;
194 if (x->uwrt == 3) { /* just did write, rewind */
195 if (!(f__cf = x->ufd = freopen(x->ufnm,f__w_mode[ufmt],x->ufd)))
196 goto cantwrite;
197 x->urw = 2;
198 }else {
199 loc=ftell(x->ufd);
200 if (!(f__cf = x->ufd =
201 freopen(x->ufnm, f__w_mode[ufmt |= 2], x->ufd)))
202 {
203 x->ufd = NULL;
204 cantwrite:
205 errno = 127;
206 return(1);
207 }
208 x->urw = 3;
209 fseek(x->ufd,loc,SEEK_SET);
210 }
211 done:
212 x->uwrt = 1;
213 return 0;
214 }
215
err__fl(int f,int m,char * s)216 int err__fl(int f, int m, char *s)
217 {
218 if (!f)
219 f__fatal(m, s);
220 if (f__doend)
221 (*f__doend)();
222 return errno = m;
223 }
224