vlp-10 using coding style in fileio.c
[vlp.git] / src / int / fileio.c
1 /*     Loglan82 Compiler&Interpreter
2      Copyright (C) 1993 Institute of Informatics, University of Warsaw
3      Copyright (C)  1993, 1994 LITA, Pau
4      
5      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by
7      the Free Software Foundation; either version 2 of the License, or
8      (at your option) any later version.
9      
10      This program is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13      GNU General Public License for more details.
14      
15              You should have received a copy of the GNU General Public License
16              along with this program; if not, write to the Free Software
17              Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19  contacts:  Andrzej.Salwicki@univ-pau.fr
20
21 or             Andrzej Salwicki
22                 LITA   Departement d'Informatique
23                 Universite de Pau
24                 Avenue de l'Universite
25                 64000 Pau   FRANCE
26                  tel.  ++33 59923154    fax. ++33 59841696
27
28 =======================================================================
29 */
30
31 #include "depend.h"
32 #include "genint.h"
33 #include "int.h"
34 #include "process.h"
35 #include "intproto.h"
36
37 #include <stdio.h>
38
39 /* File I/O routines */
40
41
42 /**
43  * Load parameters of current file
44  * @parameter expected status of file
45  * @parameter file type
46  * @parameter file object address
47  * @parameter file stream pointer
48  */
49 void loadfile(word status, word *ftype, word *am, FILE **fp)
50 {
51         word s;
52         virtaddr virt;
53
54         loadvirt(virt, currfile);
55         /* file object exists */
56         if (member(&virt, am)) {
57                 /* check status */
58                 s = M[*am + FSTAT];
59                 if (status != s && status != UNKNOWN)
60                         errsignal(RTEILLIO);
61                 *ftype = M[*am + FTYPE];
62                 *fp = MF(*am + FFILE);
63         } else {
64                 /* file not opened yet */
65                 errsignal(RTEREFTN);
66         }
67 }
68
69
70 /**
71  * Open file object
72  * @parameter TRUE iff file is temporary
73  * @parameter file type
74  * @parameter file name
75  * @parameter output virtual address
76  * @parameter output physical address
77  */
78 void genfileobj(bool ftemp, word ftyp, char *fnam, virtaddr *virt, word *am)
79 {
80         word t1;
81
82         /* generate file object */
83         request((word) APFILE, &t1, am);
84         virt->addr = t1;
85         virt->mark = M[t1 + 1];
86         M[*am + PROTNUM] = FILEOBJECT;
87         M[*am + FSTAT] = UNKNOWN;
88         M[*am + FTEMP] = lbool(ftemp);
89         M[*am + FTYPE] = ftyp;
90         MN(*am + FNAME) = fnam;
91 }
92
93 /* Prepare file for reading */
94 void reset(word am)
95 {
96         FILE *fp;
97
98         /* first close file if opened */
99         if (M[am + FSTAT] != UNKNOWN)
100                 if (fclose(MF(am + FFILE)))
101                         errsignal(RTEIOERR);
102
103         switch ((int) M[am + FTYPE]) {
104         /* open text file for reading */
105         case TEXTF:
106                 fp = fopen(MN(am + FNAME), "r");
107                 M[am + FSTAT] = READING;
108                 break;
109
110         /* open binary file for reading */
111         case CHARF:
112         case INTF:
113         case REALF:
114                 fp = fopen(MN(am + FNAME), BINARYREAD);
115                 M[am + FSTAT] = READING;
116                 break;
117
118         /* open existing file for update */
119         case DIRECT:
120                 fp = fopen(MN(am + FNAME), DIRECTOLD);
121                 M[am + FSTAT] = UPDATING;
122                 break;
123         }
124         if (fp == NULL) {
125                 M[am + FSTAT] = UNKNOWN;
126                 errsignal(RTECNTOP);
127         }
128         /* store stream pointer */
129         MF(am + FFILE) = fp;
130 }
131
132 /**
133  * Prepare file for writing
134  */
135 void rewrite(word am)
136 {
137         FILE *fp;
138
139         /* first close file if opened */
140         if (M[ am+FSTAT ] != UNKNOWN)
141                 if (fclose(MF(am + FFILE)))
142                         errsignal(RTEIOERR);
143
144         switch ((int) M[am + FTYPE]) {
145         /* open text file for writing */
146         case TEXTF:
147                 fp = fopen(MN(am + FNAME), "w");
148                 M[am + FSTAT] = WRITING;
149                 break;
150
151         /* open binary file for writing */
152         case CHARF:
153         case INTF:
154         case REALF:
155                 fp = fopen(MN(am + FNAME), BINARYWRITE);
156                 M[am + FSTAT] = WRITING;
157                 break;
158
159         /* create new file for update */
160         case DIRECT:
161                 fp = fopen(MN(am+FNAME), DIRECTNEW);
162                 M[am + FSTAT] = UPDATING;
163                 break;
164         }
165
166         if (fp == NULL) {
167                 M[am + FSTAT] = UNKNOWN;
168                 errsignal(RTECNTOP);
169         }
170         /* store stream pointer */
171         MF(am + FFILE) = fp;
172 }
173
174 /**
175  * Delete file
176  */
177 void delete(virtaddr *virt)
178 {
179         word am;
180
181         if (member(virt, &am)) {
182                 /* first close file if opened */
183                 if (M[am + FSTAT ] != UNKNOWN)
184                         if (fclose(MF(am+FFILE))) errsignal(RTEIOERR);
185
186                 /* delete file */
187                 if (unlink(MN(am+FNAME)))
188                         errsignal(RTEIOERR);
189                 /* free memory used by file name */
190                 free(MN(am+FNAME));
191                 /* and kill file object */
192                 disp(virt);
193         } else {
194                 errsignal(RTEREFTN);
195         }
196 }
197
198 /**
199  * Generate temporary file name
200  */
201 char *tempfilename()
202 {
203         char *cp;
204         static int tempcnt = 0;
205
206         cp = ballocate(10);
207         if (cp == NULL)
208                 errsignal(RTEMEMOV);
209
210         sprintf(cp, "LOG%05d", tempcnt++);
211         return cp;
212 }
213
214 /**
215  * Test for end of file
216  */
217 bool testeof(FILE *fp)
218 {
219         int ch;
220
221         ch = getc(fp);
222         ungetc(ch, fp);
223         return (ch == EOF);
224 }
225
226 /**
227  * Test for end of line
228  */
229 bool testeoln(FILE *fp)
230 {
231         int ch;
232
233         ch = getc(fp);
234         ungetc(ch, fp);
235         return (ch == '\n');
236 }
237
238 /**
239  * Skip to end of line
240  */
241 void readln(FILE *fp)
242 {
243         int ch, st;
244         G_MESSAGE msg;
245         if (fp == stdin) {
246                 read_line();
247         }
248         else {
249                 while (ch != '\n' && ch != EOF) {
250                         ch = getc(fp);
251                 }
252         }
253 }
254
255 static char str[10];
256 /**
257  * Read integer
258  */
259 word readint(FILE *fp)
260 {
261         long i = 0L;
262         int j = 0, c = 0;
263         int bool = 0;
264
265
266         while(c < '0' || c > '9') {
267                 if(c == '-')
268                         bool = 1;
269                 else
270                         bool = 0;
271
272                 c=fgetc(fp);
273
274                 if(c == EOF) {
275                         errsignal(RTEBADFM);
276                         goto END;
277                 }
278         }
279
280         do {
281                 i = 10*i + (c - '0');
282                 j++;
283                 c = fgetc(fp);
284         } while(c >= '0' && c <= '9');
285
286         if(c != EOF)
287                 ungetc(c, fp);
288         if (j == 0 )
289                 errsignal(RTEBADFM);
290
291 END:
292         if (bool)
293                 return -i;
294         else
295                 return i;
296 }
297
298 /**
299  * Read real
300  */
301 double readreal(FILE *fp)
302 {
303         double r;
304
305         if (fscanf(fp, "%lf", &r) != 1)
306                 errsignal(RTEBADFM);
307
308         return r;
309 }
310
311 /**
312  * Write integer
313  */
314 void writeint(word n, word field, FILE *fp)
315 {
316         static char format[32];
317
318         sprintf(format,"%*ld",(int)field, (long)n);
319
320         if (fp == stdout)
321                 write_str(format);
322         else if (fprintf(fp, "%*ld", (int)field, (long) n) == 0)
323                 errsignal(RTEIOERR);
324 }
325
326 /**
327  * Write real
328  */
329 void writereal(double r, word field1, word field2, FILE *fp)
330 {
331         char format[32];
332
333         sprintf(format, "%*.*lf", (int) field1, (int) field2,r);
334         if (fp == stdout)
335                 write_str(format);
336         else if (fprintf(fp,"%*.*lf", (int)field1, (int)field2, r) == 0)
337                 errsignal(RTEIOERR);
338 }
339
340 /**
341  * Write string
342  */
343 void writestring(word offset, word field, FILE *fp)
344 {
345         word len, addr;
346         int i;
347         char *cp;
348         char s[256];
349
350         addr = strings + offset;
351         len = M[addr];
352         /* pointer to first char of string */
353         cp = (char *) &M[ addr+1 ];
354         if (fp == stdout) {
355                 for(i = 0; i < len; i++)
356                         s[i] = *cp++;
357                 s[len] = '\0';
358                 write_str(s);
359         } else {
360                 while (len-- > 0 && field-- != 0) {
361                         if (putc(*cp++, fp) == EOF)
362                                 errsignal(RTEIOERR);
363                 }
364         }
365 }
366
367 /**
368  * Perform direct access read/write
369  * @parameter buffer array
370  * @parameter number of bytes to transfer
371  * @parameter fread() or fwrite()
372  * @parameter stream pointer
373  */
374 #ifndef NO_PROTOTYPES
375 word directio(virtaddr *buf, word len, int (*action)(char *,int, int, FILE *),
376                                                                 FILE *fp)
377 #else
378 word directio(virtaddr *buf, word len, int (*action)(), FILE *fp)
379 #endif
380 {
381         word am, t1, result;
382         int n;
383
384         /* file not none */
385         if (member(buf, &am)) {
386                 /* seek to current position required*/
387                 if (fseek(fp, 0L, 1))
388                         errsignal(RTEIOERR);
389                 
390                 /* check appetite */
391                 len = min(len, (M[ am ]-3)*sizeof(word));
392                 /* number of bytes transfered */
393                 result = 0;
394                 /* address in memory for transfer */
395                 t1 = am+3;
396                 /* transfer full blocks */
397                 while (len >= IOBLOCK) {
398                         n = (*action)((char *) &M[t1], 1, IOBLOCK, fp);
399                         result += n;
400                         if (n != IOBLOCK)
401                                 return result;
402                         len -= IOBLOCK;
403                         t1 += IOBLOCK / sizeof(word);
404                 }
405                 /* transfer last unfilled block */
406                 if (len > 0) {
407                         n = (*action)((char *) &M[t1], 1, (int) len, fp);
408                         result += n;
409                 }
410                 return(result);
411         }
412         else {
413                 errsignal(RTEREFTN);
414         }
415 }
416