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