source: CIVL/mods/dev.civl.com/notes/io.txt@ 1aaefd4

main test-branch
Last change on this file since 1aaefd4 was aad342c, checked in by Stephen Siegel <siegel@…>, 3 years ago

Performing huge refactor to incorporate ABC, GMC, and SARL into CIVL repo and use Java modules.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5664 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 15.4 KB
Line 
1Implementation of stdio.
2
3
4/* Array of strings: result of printing to stdout */
5$output char CIVL_stdout[][];
6
7/* Abstract functions will be declared in LibstdioExecutor.java:
8 * char[] intToString(int x, char format[])
9 * char[] floatToString(float x, char format[])
10 * char[] doubleToString(double x, char format[])
11 * etc.
12 */
13
14
15/* system function printf will be defined as follows:
16 * evaluate arguments.
17 * parse the format string to find all the % codes.
18 * check they match up with the number and types of additional args.
19 * for each code, extract the code into a separate concrete array
20 * of char.
21 * For an abstract function call for each of the above format-string-
22 * value pairs. Note that %s codes do not require abstract function
23 * since corresponding value will already have type string (char[]).
24 * Construct an array of SymbolicExpression as follows:
25 * sequence of concrete strings interleaved with abstract ones
26 * as above.
27 * Append these to CIVL_stdout.
28 */
29
30
31 Input:
32
33 strcmp(s1,s2): to determine if two strings are equal.
34 Need to assume this is true in many cases?
35 Need strcmp to return abstract function if the strings
36 are not concrete.
37
38 fscanf(file, format, buf):
39
40 $input
41
42
43
44=================================== I/O Model =========================================
45
46Representation of file contents:
47
48A file is either a text file or a binary file.
49
50Text files: the contents of a text file is a sequence of strings, i.e., a ragged array
51of char.
52
53char[][] tf; /* ragged */
54
55Each element tf[i] is a "word".
56A word is a string, i.e., an array of char.
57
58Furthermore, a word is either a white-space word (ws) or a
59non-white-space word (x). A white-space word consists of only
60white-space characters (newline, space, tab, return).
61A non-white-space word consists of only
62non-white-space characters. The elements of tf alternate between
63white-space words and non-white-space words
64
65tf may start with either a white-space word (ws) or a non-white-space
66word (x). It may end with either a ws or an x. Or, it may be empty.
67Examples:
68
69tf = {ws, x, ws, x, ..., ws, x, ws}
70tf = {x, ws, x, ..., ws, x, ws}
71tf = {ws, x, ws, x, ..., ws, x}
72tf = {x, ws, x, ..., ws, x}
73tf = {x}
74tf = {ws}
75tf = {}
76
77The following abstract functions may be used to create words:
78
79(However, I'm not sure how to represent an abstract function
80that returns a String, which is an array, since a function
81cannot return an array in C or CIVL-C. However you can do this
82in the model layer.)
83
84String intToString(int n, String format);
85String realToString(real x, String format);
86
87A position in the file is represented by an ordered pair (int, int).
88It is an index into the ragged array.
89
90Scanning: scanning reads the array and converts to either string, int, or real.
91The following abstract functions are used to convert:
92
93int stringToInt(String s, String format);
94real stringToRead(String s, String format);
95
96These satisfy:
97
98stringToInt(intToString(n,f),f) = n
99intToString(stringToInt(s,f),f) = s
100
101stringToReal(realToString(x,f),f) not necessarily equal to x (approx.)
102realToString(stringToReal(s,f),f) depends on precision of real type
103
104Note strings do not require any conversion, except that a null termination
105character is added when scanned. (Is it included when printing?)
106
107Printing adds elements to the array.
108
109Binary files: work in progress.
110
111State: each process has a process-global variable filesystem, which is a vector
112of files.
113
114File System:
115
116A file has a name, as well as contents. The name is a string.
117A process global variable in each process is used to represent the file
118system on that process. This is a vector of files.
119
120The function to open a file specifies the name. There are two possibilities:
121a file of that name already exists in the filesystem variable, or it doesn't.
122This may not be determinable. For example, a program that takes two commandline
123inputs x and y could then proceed to open x, and then open y. What results from
124this depends on whether x equals y (as strings).
125
126Question: is it legal to open a file twice, i.e, have two streams associated
127to the same file? (Why not?)
128
129FOR NOW: if we cannot determine whether two filenames are equal or not:
130assume they are not, and print a warning that we are adding this assumption.
131
132LATER: Force user to add assumption that x does not equal y? This requires
133string operations (equals, strcmp).
134
135#pragma TASS assume argc >= 3 && strcmp(argv[1],argv[2]) != 0
136
137User might even put this in his code as an assertion. (Should we have a way
138to indicate an assertion should be assumed to hold?
139
140#pragma TASS assume holds
141assert argc >= 3 && strcmp(argv[1],argv[2]) != 0
142
143In any case, if a file of that name does not exist in file system variable, it
144is added. Otherwise, the exisitng one is used.
145
146If the open command specifies write mode, the file contents are put
147in an initial empty state.
148
149If the open command specifies read mode and the file has just been added, the file
150contents are initialized with a symbolic constant of the approrpriate type.
151The length of the contents array is a symbolic constant of integer type, the ragged
152array is constructed as usual for ragged arrays.
153
154If the open command specifies read mode and the file alread existed, the file
155contents are left unchanged.
156
157Closing: closing a file does not remove it from the file system variable.
158(Only deleting the file can do that.) It simply sets a flag in the stream
159associated with the file. If the file was written to since being opened,
160it also causes the file to be copied to the output variable which is an array
161of files. If the file is already there in the output variable, it is overwritten.
162
163Multi-process programs: for now, model will be as follows: each process has
164its own filesystem, so no communication is possible across procs.
165
166Single program verification mode: no output variable is used.
167Output to stdout/stderr: simply ignored.
168Input from stdin: only one process can do it, otherwise error.
169
170Comparison mode: a single output array of output files is used. At process
171termination, output files from a process will be copied to this array.
172They will be inserted in alphabetical (or some other canonical) order.
173It is OK to have output files from different procs, as long as they have
174different names. For example, this will allow comparison of two programs,
175one sequential
176and one parallel, where the sequential one writes file OUT and the 7th
177process (say) of the parallel one writes file OUT.
178Exception: output to stdout/stderr could be ignored (commandline option).
179If not ignored, only process can write to each (but they can be two
180different procs), i.e., they are treated like all other output files.
181-ignorestdout=BOOLEAN (default: false). -ignorestderr.
182
183Also, any output statement can be preceded by #pragma TASS ignore and it
184will be ignored.
185
186
187TODO: add IO error to types of execution errors.
188
189What about format errors from scanning? ignore for now---add assumptions later.
190
191Note: make sure all streams are closed at termination. Else throw I/O error.
192
193
194=================================== Types =============================================
195
196
197The following represents a file, as well as the state of the file.
198
199A file has a filename, which is a String.
200Note: the maximum length of a filename is FILENAME_MAX, a constant defined
201in C99 Standard.
202
203An output file is one which has been written to at least once in the
204execution of the program, unless the user has explicitly said to ignore
205such writes (using the TASS ignore pragma).
206An input file is one which has been read at least once before writing
207to it.
208
209Every file is either in binary or text form.
210
211Every file has either byte or wide orientation. This is a C thing.
212It has to do with whether a character is represented by one byte, or
213more than one byte. See the C99 Standard. (Is this just for text
214files?)
215
216
217typedef struct STDIO_File {
218 char filename[]; /* the name of the file (including path) */
219 boolean isOutput; /* is this an output file? */
220 boolean isInput; /* is this an input file? */
221 boolean isBinary; /* can be binary or text */
222 boolean isWide; /* wide orientation */
223 char[][] contents; /* file contents: ragged array */
224} STDIO_File;
225
226
227The following represents a stream, which is the data structure
228used by the user program to access a file. A stream has a reference
229to a file, and some additional information.
230
231The stream is either open or closed.
232
233The stream has a reference to a certain position in the file.
234This is represented as an integer.
235
236The stream has a certain mode, coded as "r" (read), "w" (write),
237and so on. Internally, integer constants are used to represent
238the modes.
239
240typedef struct STDIO_Stream {
241 STDIO_File *file; /* file to which this stream refers */
242 boolean isOpen; /* is this stream open? */
243 int position1; /* current word in file */
244 int position2; /* character index in word */
245 int mode; /* Stream mode: r/w/a */
246} FILE;
247
248#define size_t int (integer)
249
250#define fpos_t int (integer)
251
252Notes: According to C99,
253there is also an "orientation" associated to a stream: either "byte"
254or "wide". The orientation of the stream is determined by the first I/O function
255that is applied to the stream after opening it. Here we are only dealing with
256byte streams. There are corresponding wide versions of all the functions
257for wide streams. We have put this characteristic in the file itself.
258
259=================================== Constants =========================================
260
261Note: these can be put in stdio.h
262
263These are for internal use only. They are used instead of the strings "r",
264"w", etc.:
265
266#define STDIO_MODE_READ 1
267#define STDIO_MODE_WRITE 2
268#define STDIO_MODE_APPEND 3
269
270#define stdin (FILE*)0
271#define stdout (FILE*)1
272#define stderr (FILE*)2
273
274#define EOF -1
275
276
277
278===================================== Variables =======================================
279
280File objects (instances of STDIO_File) are instanitated at runtime.
281A file is instantiated when one is opened for reading or writing.
282
283Output variable:
284Vector<STDIO_File> STDIO_outputFiles;
285
286The files that had something written to them. When an output file is closed,
287it is copied from the heap to this vector. This vector could be sorted to
288get a canonical order.
289
290Process global variable:
291Vector<STDIO_File> STDIO_filesystem
292
293This represents the state of all files in the file system on this process.
294It is initially empty. When a file is opened (whether for reading or writing)
295a file object is instantiated (if one with that filename does not already exist)
296on the heap, and a reference to it is added to this vector.
297This vector could be sorted to get a canonical order.
298
299
300================================== Abstract Functions =================================
301
302
303
304=================================== System Functions ==================================
305
306
307
308FILE *fopen(const char * restrict filename, const char * restrict mode);
309See 7.19.5.3.
310 modes:
311 r: open text file for reading
312 w: truncate if already exists, open text file for writing
313 a: open text file for writing at end (append)
314 rb: open binary file for reading.
315 wb:
316 ab:
317 all of above with "+" added.
318 returns NULL if problem
319Examples:
320 FILE *f = fopen(argv[0], "r");
321
322int fclose(FILE *stream);
323 all data is flushed automatically at close.
324 returns 0 if successful, EOF if problem.
325
326int fprintf(FILE * restrict stream, const char * restrict format, ...);
327 some of the format codes:
328%d: integer
329%f: floating-point
330%s: string, don't print the null terminating character
331 many different variations are possible
332 returns the number of characters transmitted
333 returns negative number if error
334Examples:
335 fprintf(stdout, "blah %d blah %d %f \n", a[i], n, x);
336equivalent to:
337 fprintf(stdout, "blah ");
338 fprintf(stdout, "%d", a[i]);
339 fprintf(stdout, " blah ");
340 fprintf(stdout, "%d", n);
341 fprintf(stdout, " ");
342 fprintf(stdout, "%f", x);
343 fprintf(stdout, " \n");
344translated as:
345
346int fscanf(FILE * restrict stream, const char * restrict format, ...);
347
348Notes:
349 the extra arguments are pointers to things of the appropriate type. They point
350 to where the result of the scans should go
351 the format string is a sequence of directives. each directive is either
352 an ordinary non-white-space character, a sequence of white-space characters,
353 or a conversion specification
354 each directive matches some sequence of characters in the file
355 white space directive: reads until first non-white space character
356 is encountered
357 regular non-white-space characters have to be matched exactly,
358 in which case they are scanned and ignored.
359 initial white-space characters are scanned and ignored
360 the longest character sequence matching the code is read--hence reading one
361 more character will cause non-match (or be EOF)
362 %s: matches sequence of non-white-space characters. The null tern character
363 is automatically added to the result
364 %d: matches sequence of chars which define an int
365 %f: matches sequence of chars which define a floating-point number. Needs to have
366 one of a few legal formats, such as 456.23 (note: need decimal point),
367 or exponent....see strtod, 7.20.1.3
368
369Returns:
370 number of items assigned. this can be less than number of conversion
371 specifications due to matching errors
372 EOF, if input error occurs: encoding error or unavailability of input characters
373
374Reading files.
375
376#pragma TASS system
377FILE* STDIO_openRead(char *filename, boolean isBinary, boolean isWide);
378
379#pragma TASS system
380FILE* STDIO_openWrite(char *filename, boolean isBinary, boolean isWide);
381
382/* Closing the file also causes output to be copied to output variable STDIO_outputFiles */
383#pragma TASS system
384void close(FILE *file);
385
386Use:
387
388int STDIO_scanInt(FILE *stream, int *x) {
389 *x = STDIO_SCAN_INT(*(stream->file), stream->position);
390 stream->position += sizeof(int);
391 return 1; // number of items scanned successfully
392}
393
394int STDIO_scanReal(FILE *stream, float *x) {
395 return 0;
396
397}
398
399int STDIO_scanString(FILE *stream, char *string) {
400 return 0;
401
402}
403
404/* The following takes the file and current position and returns the
405 * new value for contents after writing the int x to the file. */
406#pragma TASS abstract int STDIO_PRINT_INT(FILE file, int position, int x);
407
408void STDIO_printInt(FILE *stream, int x) {
409 stream->file->contents = STDIO_PRINT_INT(stream->file, stream->position, x);
410 stream->position += sizeof(int);
411}
412
413
414void STDIO_printReal(FILE *file, float x) {
415}
416
417void STDIO_printString(FILE *file, char *string) {
418}
419
420
421----
422
423Transformations:
424
425AST:
426
427add type STDIO_File: requires ragged array type in AST classes
428replace definition of type FILE with new definition; all references to the old type
429 now point to new type. Should not be necessary because the type itself will
430 be changed.
431modify functions?
432
433Model:
434
435add abstract functions
436for any process that uses stdio functions:
437 add process global variable STDIO_filesystem
438add output variable STDIO_outputFiles
439
440Executor:
441 implement all functions as system functions
442
443initialization?
444 each library should have opportunity to initialize state: check!
445 each library should have function called at termination: check!
446 create entries in file system for stdin, stdout, stderr.
447 but these are constants must be created in initial states
448 the last two are output files?
449 add to STDIO_filesystem: stdin, stdout, stderr files
450 open streams on them: process global variables?
451 replace references to (FILE*)0 to pointers to those streams. could be done
452 dynamically.
453 the name "stdout" is different from a user file named "stdout". Do not
454 confuse these two. add bit isSystem?
455 for printf, etc., VARIABLE ARGUMENTs
456 at termination, close the three system streams.
457
458
Note: See TracBrowser for help on using the repository browser.