1 /* Loglan82 Compiler&Interpreter
2 Copyright (C) 1993 Institute of Informatics, University of Warsaw
3 Copyright (C) 1993, 1994 LITA, Pau
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.
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.
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.
19 contacts: Andrzej.Salwicki@univ-pau.fr
22 LITA Departement d'Informatique
24 Avenue de l'Universite
26 tel. ++33 59923154 fax. ++33 59841696
28 =======================================================================
39 /* File I/O routines */
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 */
50 loadvirt(virt, currfile);
51 if (member(&virt, am)) /* file object exists */
53 s = M[ *am+FSTAT ]; /* check status */
54 if (status != s && status != UNKNOWN) errsignal(RTEILLIO);
55 *ftype = M[ *am+FTYPE ];
58 else errsignal(RTEREFTN); /* file not opened yet */
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 */
74 request((word) APFILE, &t1, am); /* generate file object */
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;
82 } /* end genfileobj */
85 void reset(am) /* Prepare file for reading */
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 ])
94 case TEXTF : /* open text file for reading */
95 fp = fopen(MN(am+FNAME), "r");
96 M[ am+FSTAT ] = READING;
99 case CHARF : /* open binary file for reading */
102 fp = fopen(MN(am+FNAME), BINARYREAD);
103 M[ am+FSTAT ] = READING;
106 case DIRECT : /* open existing file for update */
107 fp = fopen(MN(am+FNAME), DIRECTOLD);
108 M[ am+FSTAT ] = UPDATING;
113 M[ am+FSTAT ] = UNKNOWN;
116 MF(am+FFILE) = fp; /* store stream pointer */
120 void rewrite(am) /* Prepare file for writing */
125 if (M[ am+FSTAT ] != UNKNOWN) /* first close file if opened */
126 if (fclose(MF(am+FFILE))) errsignal(RTEIOERR);
128 switch ((int) M[ am+FTYPE ])
130 case TEXTF : /* open text file for writing */
131 fp = fopen(MN(am+FNAME), "w");
132 M[ am+FSTAT ] = WRITING;
135 case CHARF : /* open binary file for writing */
138 fp = fopen(MN(am+FNAME), BINARYWRITE);
139 M[ am+FSTAT ] = WRITING;
142 case DIRECT : /* create new file for update */
143 fp = fopen(MN(am+FNAME), DIRECTNEW);
144 M[ am+FSTAT ] = UPDATING;
149 M[ am+FSTAT ] = UNKNOWN;
152 MF(am+FFILE) = fp; /* store stream pointer */
156 void delete(virt) /* Delete file */
161 if (member(virt, &am))
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 */
169 else errsignal(RTEREFTN);
173 char *tempfilename() /* Generate temporary file name */
176 static int tempcnt = 0;
179 if (cp == NULL) errsignal(RTEMEMOV);
180 sprintf(cp, "LOG%05d", tempcnt++);
182 } /* end tempfilename */
185 bool testeof(fp) /* Test for end of file */
196 bool testeoln(fp) /* Test for end of line */
207 void readln(fp) /* Skip to end of line */
217 while (ch != '\n' && ch != EOF)
224 word readint(fp) /* Read integer */
232 while(c<'0' || c>'9'){
248 }while(c>='0' && c<='9');
249 if(c!=EOF) ungetc(c,fp);
250 if (j == 0 ) errsignal(RTEBADFM);
259 double readreal(fp) /* Read real */
264 if (fscanf(fp, "%lf", &r) != 1) errsignal(RTEBADFM);
269 void writeint(n, field, fp) /* Write integer */
273 static char format[ 32 ];
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);
281 void writereal(r, field1, field2, fp) /* Write real */
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)
292 } /* end writereal */
295 void writestring(offset, field, fp) /* Write string */
305 addr = strings+offset;
307 cp = (char *) &M[ addr+1 ]; /* pointer to first char of string */
310 for(i=0;i<len;i++) s[i] = *cp++;
314 while (len-- > 0 && field-- != 0)
315 if (putc(*cp++, fp) == EOF) errsignal(RTEIOERR);
316 } /* end writestring */
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() */
325 int (*action)(); /* fread() or fwrite() */
327 FILE *fp; /* stream pointer */
332 if (member(buf, &am)) /* file not none */
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 */
341 n = (*action)((char *) &M[ t1 ], 1, IOBLOCK, fp);
343 if (n != IOBLOCK) return(result);
345 t1 += IOBLOCK/sizeof(word);
347 if (len > 0) /* transfer last unfilled block */
349 n = (*action)((char *) &M[ t1 ], 1, (int) len, fp);
354 else errsignal(RTEREFTN);