Added upstream version.
[vlp.git] / 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 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,st;
211     G_MESSAGE msg;
212    if (fp == stdin)
213     {
214       read_line();
215     }
216      else
217     while (ch != '\n' && ch != EOF)
218           ch=getc(fp);
219
220 } /* end readln */
221
222
223 static char str[10];
224 word readint(fp)                        /* Read integer */
225 FILE *fp;
226 {
227     long i=0L;
228     int j=0,c=0;
229     int bool=0;
230
231
232     while(c<'0' || c>'9'){
233        if(c=='-') bool=1;
234        else bool=0;
235      
236        c=fgetc(fp);
237
238        if(c==EOF){
239           errsignal(RTEBADFM);
240           goto END;
241        }
242     }
243     
244     do{
245        i=10*i+(c-'0');
246        j++;
247        c=fgetc(fp);
248     }while(c>='0' && c<='9');
249     if(c!=EOF) ungetc(c,fp);
250     if (j == 0 ) errsignal(RTEBADFM);
251  END:
252     if(bool)
253       return(-i);
254     else
255      return (i);
256 } /* end readint */
257
258
259 double readreal(fp)                     /* Read real */
260 FILE *fp;
261 {
262     double r;
263
264     if (fscanf(fp, "%lf", &r) != 1) errsignal(RTEBADFM);
265     return (r);
266 } /* end readreal */
267
268
269 void writeint(n, field, fp)             /* Write integer */
270 word n, field;
271 FILE *fp;
272 {
273  static char format[ 32 ];
274
275     sprintf(format,"%*ld",(int)field, (long)n); 
276     if (fp == stdout) write_str(format); else
277     if (fprintf(fp, "%*ld", (int)field, (long) n) == 0) errsignal(RTEIOERR);
278 } /* end writeint */
279
280
281 void writereal(r, field1, field2, fp)   /* Write real */
282 double r;
283 word field1, field2;
284 FILE *fp;
285 {
286   char format[ 32 ];
287
288     sprintf(format, "%*.*lf", (int) field1, (int) field2,r);
289     if (fp == stdout) write_str(format); else
290     if (fprintf(fp,"%*.*lf", (int)field1, (int)field2, r) == 0)
291        errsignal(RTEIOERR);
292 } /* end writereal */
293
294
295 void writestring(offset, field, fp)     /* Write string */
296 word offset;
297 word field;
298 FILE *fp;
299 {
300     word len, addr;
301     int i;
302     char *cp;
303     char s[256];
304
305     addr = strings+offset;
306     len = M[ addr ];
307     cp = (char *) &M[ addr+1 ];         /* pointer to first char of string */
308    if (fp == stdout) 
309     { 
310       for(i=0;i<len;i++) s[i] = *cp++;
311       s[len] = '\0';
312       write_str(s);
313     } else
314     while (len-- > 0 && field-- != 0)
315         if (putc(*cp++, fp) == EOF) errsignal(RTEIOERR);
316 } /* end writestring */
317
318
319 word directio(buf, len, action, fp)     /* Perform direct access read/write */
320 virtaddr *buf;                          /* buffer array */
321 word len;                               /* number of bytes to transfer */
322 #ifndef NO_PROTOTYPES
323 int (*action)(char *,int,int,FILE *);   /* fread() or fwrite() */
324 #else
325 int (*action)();                        /* fread() or fwrite() */
326 #endif
327 FILE *fp;                               /* stream pointer */
328 {
329     word am, t1, result;
330     int n;
331
332     if (member(buf, &am))               /* file not none */
333     {
334         if (fseek(fp, 0L, 1)) errsignal(RTEIOERR);      /* seek to current */
335                                                         /* position required */
336         len = min(len, (M[ am ]-3)*sizeof(word));       /* check appetite */
337         result = 0;                     /* number of bytes transfered */
338         t1 = am+3;                      /* address in memory for transfer */
339         while (len >= IOBLOCK)          /* transfer full blocks */
340         {
341             n = (*action)((char *) &M[ t1 ], 1, IOBLOCK, fp);
342             result += n;
343             if (n != IOBLOCK) return(result);
344             len -= IOBLOCK;
345             t1 += IOBLOCK/sizeof(word);
346         }
347         if (len > 0)                    /* transfer last unfilled block */
348         {
349             n = (*action)((char *) &M[ t1 ], 1, (int) len, fp);
350             result += n;
351         }
352         return(result);
353     }
354     else errsignal(RTEREFTN);
355 } /* end directio */
356