Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / new-s5r4 / 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 void loadfile(status, ftype, am, fp)    /* Load parameters of current file */
42 word status;                            /* expected status of file */
43 word *ftype;                            /* file type */
44 word *am;                               /* file object address */
45 FILE **fp;                              /* file stream pointer */
46 {
47     word s;
48     virtaddr virt;
49
50     loadvirt(virt, currfile);
51     if (member(&virt, am))              /* file object exists */
52     {
53         s = M[ *am+FSTAT ];             /* check status */
54         if (status != s && status != UNKNOWN) errsignal(RTEILLIO);
55         *ftype = M[ *am+FTYPE ];
56         *fp = MF(*am+FFILE);
57     }
58     else errsignal(RTEREFTN);           /* file not opened yet */
59 } /* end loadfile */
60
61
62 /* Open file object
63  */
64
65 void genfileobj(ftemp, ftyp, fnam, virt, am)
66 bool ftemp;                             /* TRUE iff file is temporary */
67 word ftyp;                              /* file type */
68 char *fnam;                             /* file name */
69 virtaddr *virt;                         /* output virtual address */
70 word *am;                               /* output physical address */
71 {
72     word t1;
73
74     request((word) APFILE, &t1, am);    /* generate file object */
75     virt->addr = t1;
76     virt->mark = M[ t1+1 ];
77     M[ *am+PROTNUM ] = FILEOBJECT;
78     M[ *am+FSTAT ] = UNKNOWN;
79     M[ *am+FTEMP ] = lbool(ftemp);
80     M[ *am+FTYPE ] = ftyp;
81     MN(*am+FNAME) = fnam;
82 } /* end genfileobj */
83
84
85 void reset(am)                          /* Prepare file for reading */
86 word am;
87 {
88     FILE *fp;
89
90     if (M[ am+FSTAT ] != UNKNOWN)       /* first close file if opened */
91         if (fclose(MF(am+FFILE))) errsignal(RTEIOERR);
92     switch ((int) M[ am+FTYPE ])
93     {
94         case TEXTF  :                   /* open text file for reading */
95                 fp = fopen(MN(am+FNAME), "r");
96                 M[ am+FSTAT ] = READING;
97                 break;
98         
99         case CHARF  :                   /* open binary file for reading */
100         case INTF   :
101         case REALF  :
102                 fp = fopen(MN(am+FNAME), BINARYREAD);
103                 M[ am+FSTAT ] = READING;
104                 break;
105         
106         case DIRECT :                   /* open existing file for update */
107                 fp = fopen(MN(am+FNAME), DIRECTOLD);
108                 M[ am+FSTAT ] = UPDATING;
109                 break;
110     }
111     if (fp == NULL)
112     {
113         M[ am+FSTAT ] = UNKNOWN;
114         errsignal(RTECNTOP);
115     }
116     MF(am+FFILE) = fp;                  /* store stream pointer */
117 } /* end reset */
118
119         
120 void rewrite(am)                        /* Prepare file for writing */
121 word am;
122 {
123     FILE *fp;
124
125     if (M[ am+FSTAT ] != UNKNOWN)       /* first close file if opened */
126         if (fclose(MF(am+FFILE))) errsignal(RTEIOERR);
127
128     switch ((int) M[ am+FTYPE ])
129     {
130         case TEXTF  :                   /* open text file for writing */
131                 fp = fopen(MN(am+FNAME), "w");
132                 M[ am+FSTAT ] = WRITING;
133                 break;
134         
135         case CHARF  :                   /* open binary file for writing */
136         case INTF   :
137         case REALF  :
138                 fp = fopen(MN(am+FNAME), BINARYWRITE);
139                 M[ am+FSTAT ] = WRITING;
140                 break;
141         
142         case DIRECT :                   /* create new file for update */
143                 fp = fopen(MN(am+FNAME), DIRECTNEW);
144                 M[ am+FSTAT ] = UPDATING;
145                 break;
146     }
147     if (fp == NULL)
148     {
149         M[ am+FSTAT ] = UNKNOWN;
150         errsignal(RTECNTOP);
151     }
152     MF(am+FFILE) = fp;                  /* store stream pointer */
153 } /* end rewrite */
154
155
156 void delete(virt)                       /* Delete file */
157 virtaddr *virt;
158 {
159     word am;
160
161     if (member(virt, &am))
162     {
163         if (M[ am+FSTAT ] != UNKNOWN)   /* first close file if opened */
164             if (fclose(MF(am+FFILE))) errsignal(RTEIOERR);
165         if (unlink(MN(am+FNAME))) errsignal(RTEIOERR);  /* delete file */
166         free(MN(am+FNAME));             /* free memory used by file name */
167         disp(virt);                     /* and kill file object */
168     }
169     else errsignal(RTEREFTN);
170 } /* end delete */
171
172
173 char *tempfilename()                    /* Generate temporary file name */
174 {
175     char *cp;
176     static int tempcnt = 0;
177
178     cp = ballocate(10);
179     if (cp == NULL) errsignal(RTEMEMOV);
180     sprintf(cp, "LOG%05d", tempcnt++);
181     return (cp);
182 } /* end tempfilename */
183
184
185 bool testeof(fp)                        /* Test for end of file */
186 FILE *fp;
187 {
188     int ch;
189
190     ch = getc(fp);
191     ungetc(ch, fp);
192     return (ch == EOF);
193 } /* end testeof */
194
195
196 bool testeoln(fp)                       /* Test for end of line */
197 FILE *fp;
198 {
199     int ch;
200
201     ch = getc(fp);
202     ungetc(ch, fp);
203     return (ch == '\n');
204 } /* end testeoln */
205
206
207 void readln(fp)                         /* Skip to end of line */
208 FILE *fp;
209 {
210     int ch;
211
212     while ((ch = getc(fp)) != '\n' && ch != EOF) ;
213 } /* end readln */
214
215
216 static char str[10];
217 word readint(fp)                        /* Read integer */
218 FILE *fp;
219 {
220     long i=0L;
221     int j=0,c=0;
222     int bool=0;
223     while(c<'0' || c>'9'){
224        if(c=='-') bool=1;
225        else bool=0;
226        c=fgetc(fp);
227        if(c==EOF){
228           errsignal(RTEBADFM);
229           goto END;
230        }
231     }
232     
233     do{
234        i=10*i+(c-'0');
235        j++;
236        c=fgetc(fp);
237     }while(c>='0' && c<='9');
238     if(c!=EOF) ungetc(c,fp);
239     if (j == 0 ) errsignal(RTEBADFM);
240  END:
241     if(bool)
242       return(-i);
243     else
244      return (i);
245 } /* end readint */
246
247
248 double readreal(fp)                     /* Read real */
249 FILE *fp;
250 {
251     double r;
252
253     if (fscanf(fp, "%lf", &r) != 1) errsignal(RTEBADFM);
254     return (r);
255 } /* end readreal */
256
257
258 void writeint(n, field, fp)             /* Write integer */
259 word n, field;
260 FILE *fp;
261 {
262 /* PS&MM   static char format[ 32 ];
263
264     sprintf(format,"%%%dld",(int)field); */
265     if (fprintf(fp, "%*ld", (int)field, (long) n) == 0) errsignal(RTEIOERR);
266 } /* end writeint */
267
268
269 void writereal(r, field1, field2, fp)   /* Write real */
270 double r;
271 word field1, field2;
272 FILE *fp;
273 {
274 /* PS&MM   char format[ 32 ];
275
276     sprintf(format, "%%%d.%dlf", (int) field1, (int) field2);
277     if (fprintf(fp, format, r) == 0) errsignal(RTEIOERR);
278 */
279     if (fprintf(fp,"%*.*lf", (int)field1, (int)field2, r) == 0)
280        errsignal(RTEIOERR);
281 } /* end writereal */
282
283
284 void writestring(offset, field, fp)     /* Write string */
285 word offset;
286 word field;
287 FILE *fp;
288 {
289     word len, addr;
290     char *cp;
291
292     addr = strings+offset;
293     len = M[ addr ];
294     cp = (char *) &M[ addr+1 ];         /* pointer to first char of string */
295     while (len-- > 0 && field-- != 0)
296         if (putc(*cp++, fp) == EOF) errsignal(RTEIOERR);
297 } /* end writestring */
298
299
300 word directio(buf, len, action, fp)     /* Perform direct access read/write */
301 virtaddr *buf;                          /* buffer array */
302 word len;                               /* number of bytes to transfer */
303 #ifndef NO_PROTOTYPES
304 int (*action)(char *,int,int,FILE *);   /* fread() or fwrite() */
305 #else
306 int (*action)();                        /* fread() or fwrite() */
307 #endif
308 FILE *fp;                               /* stream pointer */
309 {
310     word am, t1, result;
311     int n;
312
313     if (member(buf, &am))               /* file not none */
314     {
315         if (fseek(fp, 0L, 1)) errsignal(RTEIOERR);      /* seek to current */
316                                                         /* position required */
317         len = min(len, (M[ am ]-3)*sizeof(word));       /* check appetite */
318         result = 0;                     /* number of bytes transfered */
319         t1 = am+3;                      /* address in memory for transfer */
320         while (len >= IOBLOCK)          /* transfer full blocks */
321         {
322             n = (*action)((char *) &M[ t1 ], 1, IOBLOCK, fp);
323             result += n;
324             if (n != IOBLOCK) return(result);
325             len -= IOBLOCK;
326             t1 += IOBLOCK/sizeof(word);
327         }
328         if (len > 0)                    /* transfer last unfilled block */
329         {
330             n = (*action)((char *) &M[ t1 ], 1, (int) len, fp);
331             result += n;
332         }
333         return(result);
334     }
335     else errsignal(RTEREFTN);
336 } /* end directio */
337