file, filestatement − RWP*Load Simulator use of files
identifier ( >= | >>= | <= | >|= | <|= ) concatenation
identifier := null
filestatement ::= write identifier , concatenation { , concatenation } | writeline identifier { , concatenation } | readline identifier , identifier { , identifier } | fflush identifier | print concatenation { , concatenation } | printline concatenation { , concatenation } | printline readloop ::= for readline identifier , identifier { , identifier } [ and expression ] loop statementlist end [ loop ]
File in rwloadsim is implemented using FILE * from the standard I/O library in C. A file is declared like other simple types and can be declared publicly, privately or locally, but cannot be used as an argument to procedures or functions. Files are treated line-oriented although they are fully buffered by the standard I/O library. Files can be opened for reading and writing similar to how the fopen(3) call does it and can be used as pipe-lines similar to how popen(3) does it.
To open a file, assign an expression containing a string to the variable, and to close a file, assign null to it.
To open a file, use one of the assignment syntaxes where the variable v must be a file, and the concatenation is taken as the name of the file or a pipeline to be executed.
v >= e
Open a file for writing.
v >>= e
Open the file for appending, i.e. write at the end of the file.
v <= e
Open a file for reading.
v >|= e
Open a pipeline for writing; the concatenation will be given to the popen() call with a second argument of "w".
v <|= e
Open a pipeline for reading; the concatenation will be given to the popen() call with a second argument of "r".
v := null
Close a file or pipeline.
In the cases where an ordinary file (and not a pipe-line) is opened, environment expansion of $NAME or ${NAME} is done similar to how it is done in the shell, unless the --no-nameexpand option or the $namexpand:off directive is in effect. You can also use $n where n is a single digit between 1 and 9 to expand the value of a positional argument to rwloadsim. This is not done for pipelines, although the popen call is likely to do it. The same syntax with $ for environment expansion is also used on Microsoft Windows.
If the concatenation is null the file will be closed or the pipe-line terminated. You can use any of the assign operators to do so.
write v, e1 [, e2, ... ]
print e1 [, e2, ... ]
writeline v [, e1 ... ]
printline [e1 ... ]
Write the concatenations e1, e2, etc to the named file with a single space character between each. The writeline statement (that does not require any actual concatenation arguments) will additionally write a new-line. The print and printline perform the same although writing to stdout.
For more advanced output, use printfstatement(1rwl).
fflush v
Flush the file identified by the variable v; this effectively calls fflush(3).
readline v,s
The identifier v must be a file, and the identifier s must be a string. The statement reads one line from the file up to and including the newline character and assigns the line except the terminating newline character to the string s.
readline v, i1, i2, ...
The identifier v must be a file from which a line is read. The line is split into white-space separated tokens that are assigned to the variable i1, i2, etc. If fewer tokens than variables are found, the last will be assigned null even if they are of type string. If there are too few variables to receive all tokens, the last variable will have the remaining part of the line assigned to it. In all cases, if the variables are not of type string, the usual implicit conversion to either integer or double will take place.
for readline v, i1, i2 and e loop s;s;s; end
The readloop reads lines from a file and writes them into variables. The first identifier, v, must be a variable of type file that is open for read. The semantics of the readline loop is somewhat similar to the semantics of doing something like while read ... ; do in the shell. If there is only one variable, i1, in addition to the file variable, that variable must be of type string and the full line read from the file (excluding the terminating newline) will be saved in that variable.
If there are multiple variables, i1, i2, ... they can be of type integer, double or string. In that case, it is assumed that each line of the file contains white-space separated tokens. The first of these will be saved in the first variable, i1, the second in the second variable, i2, etc. If there are more tokens in the line read from the file than there are variables to save those into, the last variable will contain the remaining part of the line. If there are fewer tokens in the line read from the file than there are variables, the last ones will be null, even if they are of type string.
If you need more complex processing of input lines, use the first form with only one string variable to contain the whole line, which you subsequently process using regex or regexextract.
When end-of-file is reached, the loop terminates; you still need to explicitly close the file.
The optional and expression before the loop keyword, causes reading to stop when the expression, e, is zero; You can similarly use a break statement. In either case, you can continue reading from the file.
You can operate on stdin, stdout or stderr by using the predefined variables named stdin, stdout or stderr respectively. Do not close these.
Otherwise, it is an error not to close files or pipe-lines.
Files and pipe-lines can very well be opened, operated upon and closed in threads. If you open files with the same name in multiple threads, the behavior is unspecified.
If you have files opened for read in your main program, they will be closed in threads. This is also the case for stdin.
If you have files opened for write in your main program, they will continue to be open in threads. However, there is no guarantee that the writes from different threads are going to be separated. In fact, it is typically the case that writes from different threads will be mixed, even if you use fflush. This behavior is also happening for stdout and stderr.
The readline statement as well as the readloop read the line from their input into a buffer that by default is 2050 bytes long. If the actual line is longer than 2050 bytes, it will be truncated and an error will be printed. The buffer can be increased using the --readbuffer option to rwloadsim.
In previous versions of rwloadsim, the := assignment operator existed and the contents of the concatenation was interpreted to open for read, write, append or as pipelines. The actual operation was chosen by having an initial "<", ">>", "|" or a final "|" in the concatenation. Without any of these, the file would be opened for writing. There is a security concern with this, and it is therefore desupported in release 3.1.
Still to come.
Copyright
© 2023 Oracle Corporation
Licensed under the Universal Permissive License v 1.0 as
shown at https://oss.oracle.com/licenses/upl
variable(1rwl), statement(1rwl), threadexecution(1rwl), expression(1rwl), readloop(1rwl), compoundstatement(1rwl), printfstatement(1rwl), regex(1rwl)