(********************************************************************) (* *) (* enable_io.s7i Templates to enable file I/O for a given type *) (* Copyright (C) 1989 - 2018 Thomas Mertes *) (* *) (* This file is part of the Seed7 Runtime Library. *) (* *) (* The Seed7 Runtime Library is free software; you can *) (* redistribute it and/or modify it under the terms of the GNU *) (* Lesser General Public License as published by the Free Software *) (* Foundation; either version 2.1 of the License, or (at your *) (* option) any later version. *) (* *) (* The Seed7 Runtime Library is distributed in the hope that it *) (* will be useful, but WITHOUT ANY WARRANTY; without even the *) (* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *) (* PURPOSE. See the GNU Lesser General Public License for more *) (* details. *) (* *) (* You should have received a copy of the GNU Lesser General *) (* Public License along with this program; if not, write to the *) (* Free Software Foundation, Inc., 51 Franklin Street, *) (* Fifth Floor, Boston, MA 02110-1301, USA. *) (* *) (********************************************************************) include "file.s7i"; var file: IN is forward; var file: OUT is forward; (** * Template function to define input functions for ''aType''. * It defines the functions [[#read(inout_aType)|read]] and * [[#readln(inout_aType)|readln]]. The functions read a * whitespace terminated word respectively a line as * [[string]]. Afterwards the ''parse'' operator is used to * convert the ''string'' to an ''aType'' value. The functions * [[#read(inout_file,inout_aType)|read]] and * [[#readln(inout_file,inout_aType)|readln]] are defined with * [[file]] argument and without [[file]] argument. The * functions without [[file]] argument use the standard * input file [[stdio#IN|IN]]. * const type: myType is ... * const func myType is (attr myType) parse (in string: stri) is ... * enable_input(myType); * Afterwards it is possible to read ''myType'' values from a file. *) const proc: enable_input (in type: aType) is func begin (** * Read ''aVar'' from a word read from ''inFile''. * Before reading the word it skips spaces and tabs. The function * accepts words ending with " ", "\t", end-of-line or [[char#EOF|EOF]]. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left inFile.bufferChar contains the * word ending character (' ', '\t', '\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the word to the type ''aType''. *) const proc: read (inout file: inFile, inout aType: aVar) is func begin aVar := aType parse getwd(inFile); end func; (** * Read ''aVar'' from a word read from ''inFile'' or use ''defaultValue''. * Before reading the word it skips spaces and tabs. The function * accepts words ending with " ", "\t", end-of-line or [[char#EOF|EOF]]. * If the word is empty ''defaultValue'' is assigned to ''aVar''. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left inFile.bufferChar contains the * word ending character (' ', '\t', '\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the word to the type ''aType''. *) const proc: read (inout file: inFile, inout aType: aVar, in aType: defaultValue) is func local var string: stri is ""; begin stri := getwd(inFile); if stri = "" then aVar := defaultValue; else aVar := aType parse stri; end if; end func; (** * Read ''aVar'' from a line read from ''inFile''. * The function reads a string up to end-of-line or [[char#EOF|EOF]]. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left inFile.bufferChar contains the * line ending character ('\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the line to the type ''aType''. *) const proc: readln (inout file: inFile, inout aType: aVar) is func begin aVar := aType parse trimValue(aType, getln(inFile)); end func; (** * Read ''aVar'' from a line read from ''inFile'' or use ''defaultValue''. * The function reads a string up to end-of-line or [[char#EOF|EOF]]. * If the line is empty ''defaultValue'' is assigned to ''aVar''. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left inFile.bufferChar contains the * line ending character ('\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the line to the type ''aType''. *) const proc: readln (inout file: inFile, inout aType: aVar, in aType: defaultValue) is func local var string: stri is ""; begin stri := getln(inFile); if stri = "" then aVar := defaultValue; else aVar := aType parse trimValue(aType, stri); end if; end func; (** * Read ''aVar'' from a word read from the standard input file [[stdio#IN|IN]]. * Before reading the word it skips spaces and tabs. The function * accepts words ending with " ", "\t", end-of-line or [[char#EOF|EOF]]. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left [[stdio#IN|IN]].bufferChar contains the * word ending character (' ', '\t', '\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the word to the type ''aType''. *) const proc: read (inout aType: aVar) is func begin read(IN, aVar); end func; (** * Read ''aVar'' from a word read from standard input ([[stdio#IN|IN]]) or use ''defaultValue''. * Before reading the word it skips spaces and tabs. The function * accepts words ending with " ", "\t", end-of-line or [[char#EOF|EOF]]. * If the word is empty ''defaultValue'' is assigned to ''aVar''. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left [[stdio#IN|IN]].bufferChar contains the * word ending character (' ', '\t', '\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the word to the type ''aType''. *) const proc: read (inout aType: aVar, in aType: defaultValue) is func begin read(IN, aVar, defaultValue); end func; (** * Read ''aVar'' from a line read from the standard input file [[stdio#IN|IN]]. * The function reads a string up to end-of-line or [[char#EOF|EOF]]. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left [[stdio#IN|IN]].bufferChar contains the * line ending character ('\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the line to the type ''aType''. *) const proc: readln (inout aType: aVar) is func begin readln(IN, aVar); end func; (** * Read ''aVar'' from a line read from standard input ([[stdio#IN|IN]]) or use ''defaultValue''. * The function reads a string up to end-of-line or [[char#EOF|EOF]]. * If the line is empty ''defaultValue'' is assigned to ''aVar''. * The conversion to the type ''aType'' is done with the ''parse'' * operator. When the function is left [[stdio#IN|IN]].bufferChar contains the * line ending character ('\n' or [[char#EOF|EOF]]). * @exception RANGE_ERROR If the ''parse'' operator cannot convert * the line to the type ''aType''. *) const proc: readln (inout aType: aVar, in aType: defaultValue) is func begin readln(IN, aVar, defaultValue); end func; end func; (** * Template function to define output functions for ''aType''. * It defines the functions [[#write(in_aType)|write]] * and [[#writeln(in_aType)|writeln]] and the operators * [[#(in_aType)lpad(in_integer)|lpad]], [[#(in_aType)rpad(in_integer)|rpad]] * and [[#(in_string)<&(in_aType)|<&]]. The functions and operators use * the ''str'' function to convert the ''aType'' value to a [[string]]. * Afterwards they call the corresponding function respectively operator * for [[string]] values. The functions [[#write(inout_file,in_aType)|write]] * and [[#writeln(inout_file,in_aType)|writeln]] are defined with [[file]] * argument and without [[file]] argument. The functions without [[file]] * argument write to the standard output file [[stdio#OUT|OUT]]. * const type: myType is ... * const func string: str (in myType: myTypeValue) is ... * enable_output(myType); * Afterwards it is possible to write ''myType'' values to a file. *) const proc: enable_output (in type: aType) is func begin (** * Write ''aValue'' to the [[file]] ''outFile''. *) const proc: write (inout file: outFile, in aType: aValue) is func begin write(outFile, str(aValue)); end func; (** * Write ''aValue'' followed by end-of-line to the [[file]] ''outFile''. *) const proc: writeln (inout file: outFile, in aType: aValue) is func begin writeln(outFile, str(aValue)); end func; (** * Write ''aValue'' to the standard output file [[stdio#OUT|OUT]]. *) const proc: write (in aType: aValue) is func begin write(OUT, aValue); end func; (** * Write ''aValue'' followed by end-of-line to the standard output file [[stdio#OUT|OUT]]. *) const proc: writeln (in aType: aValue) is func begin writeln(OUT, aValue); end func; (** * Convert ''aValue'' to [[string]] and pad it with spaces at the left side. * The [[string]] is padded up to a given length. * @return ''aValue'' converted to string and left padded with spaces. *) const func string: (in aType: aValue) lpad (in integer: leng) is return str(aValue) lpad leng; (** * Convert ''aValue'' to [[string]] and pad it with spaces at the right side. * The [[string]] is padded up to a given length. * @return ''aValue'' converted to string and right padded with spaces. *) const func string: (in aType: aValue) rpad (in integer: leng) is return str(aValue) rpad leng; (** * Convert ''aValue'' to [[string]] and append it to ''stri''. * This operator is intended for write statements. * @return the result of the concatenation. *) const func string: (in string: stri) <& (in aType: aValue) is return stri & str(aValue); (** * Convert ''aValue'' to [[string]] and append ''stri'' to it. * This operator is intended for write statements. * @return the result of the concatenation. *) const func string: (in aType: aValue) <& (in string: stri) is return str(aValue) & stri; end func; (** * Template function to define I/O functions for ''aType''. * It defines the functions [[#read(inout_aType)|read]], * [[#readln(inout_aType)|readln]], [[#write(in_aType)|write]] * and [[#writeln(in_aType)|writeln]] and the * operators [[#(in_aType)lpad(in_integer)|lpad]], * [[#(in_aType)rpad(in_integer)|rpad]] * and [[#(in_string)<&(in_aType)|<&]]. To do this it * calls the templates [[#enable_input(in_type)|enable_input]] and * [[#enable_output(in_type)|enable_output]]. * const type: myType is ... * const func myType is (attr myType) parse (in string: stri) is ... * const func string: str (in myType: myTypeValue) is ... * enable_io(myType); * Afterwards it is possible to read and write ''myType'' values. *) const proc: enable_io (in type: aType) is func begin enable_input(aType); enable_output(aType); end func; enable_io(char); enable_io(integer); enable_io(boolean); enable_io(bitset); enable_output(void); # enable_output(type); # enable_output(ACTION);