]>
Commit | Line | Data |
---|---|---|
1eee94d3 GM |
1 | (* WholeIO.mod implement the ISO WholeIO specification. |
2 | ||
a945c346 | 3 | Copyright (C) 2008-2024 Free Software Foundation, Inc. |
1eee94d3 GM |
4 | Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
5 | ||
6 | This file is part of GNU Modula-2. | |
7 | ||
8 | GNU Modula-2 is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 3, or (at your option) | |
11 | any later version. | |
12 | ||
13 | GNU Modula-2 is distributed in the hope that it will be useful, but | |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | General Public License for more details. | |
17 | ||
18 | Under Section 7 of GPL version 3, you are granted additional | |
19 | permissions described in the GCC Runtime Library Exception, version | |
20 | 3.1, as published by the Free Software Foundation. | |
21 | ||
22 | You should have received a copy of the GNU General Public License and | |
23 | a copy of the GCC Runtime Library Exception along with this program; | |
24 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
25 | <http://www.gnu.org/licenses/>. *) | |
26 | ||
27 | IMPLEMENTATION MODULE WholeIO ; | |
28 | ||
29 | FROM ConvTypes IMPORT ScanClass, ScanState ; | |
30 | FROM TextIO IMPORT WriteChar, ReadChar ; | |
31 | FROM DynamicStrings IMPORT String, char, KillString, Length ; | |
32 | FROM StringConvert IMPORT IntegerToString, CardinalToString ; | |
33 | FROM WholeConv IMPORT ScanInt, ScanCard ; | |
34 | FROM StringChan IMPORT writeString ; | |
35 | FROM IOConsts IMPORT ReadResults ; | |
509eef93 | 36 | FROM TextUtil IMPORT SkipSpaces ; |
1eee94d3 GM |
37 | |
38 | ||
39 | (* Input and output of whole numbers in decimal text form | |
40 | over specified channels. The read result is of the | |
41 | type IOConsts.ReadResults. | |
42 | *) | |
43 | ||
1eee94d3 GM |
44 | |
45 | (* The text form of a signed whole number is | |
46 | ["+" | "-"], decimal digit, {decimal digit} | |
47 | ||
48 | The text form of an unsigned whole number is | |
49 | decimal digit, {decimal digit} | |
50 | *) | |
51 | ||
52 | PROCEDURE ReadInt (cid: IOChan.ChanId; VAR int: INTEGER) ; | |
53 | (* Skips leading spaces, and removes any remaining characters | |
54 | from cid that form part of a signed whole number. The | |
55 | value of this number is assigned to int. The read result | |
56 | is set to the value allRight, outOfRange, wrongFormat, | |
57 | endOfLine, or endOfInput. | |
58 | *) | |
59 | VAR | |
60 | chClass : ScanClass ; | |
61 | nextState: ScanState ; | |
62 | c : CARDINAL ; | |
63 | ch : CHAR ; | |
64 | negative : BOOLEAN ; | |
65 | BEGIN | |
509eef93 | 66 | SkipSpaces (cid) ; |
1eee94d3 GM |
67 | ReadChar(cid, ch) ; |
68 | negative := FALSE ; | |
69 | c := 0 ; | |
70 | nextState := ScanInt ; | |
71 | REPEAT | |
72 | nextState(ch, chClass, nextState) ; | |
73 | IF chClass=valid | |
74 | THEN | |
75 | IF ch='+' | |
76 | THEN | |
77 | (* ignore *) | |
78 | ELSIF ch='-' | |
79 | THEN | |
80 | negative := NOT negative | |
81 | ELSE | |
82 | c := c*10+(ORD(ch)-ORD('0')) | |
83 | END ; | |
84 | ReadChar(cid, ch) | |
85 | ELSIF chClass=padding | |
86 | THEN | |
87 | ReadChar(cid, ch) | |
88 | END | |
89 | UNTIL (chClass=invalid) OR (chClass=terminator) ; | |
90 | IF chClass=terminator | |
91 | THEN | |
92 | IF negative | |
93 | THEN | |
94 | IF c=VAL(CARDINAL, MAX(INTEGER))+1 | |
95 | THEN | |
96 | int := MIN(INTEGER) | |
97 | ELSIF c<=VAL(CARDINAL, MAX(INTEGER)) | |
98 | THEN | |
99 | int := -VAL(INTEGER, c) | |
100 | ELSE | |
101 | (* overflow *) | |
102 | IOChan.SetReadResult(cid, outOfRange) | |
103 | END | |
104 | ELSE | |
105 | int := c | |
106 | END | |
107 | END | |
108 | END ReadInt ; | |
109 | ||
110 | ||
111 | PROCEDURE WriteInt (cid: IOChan.ChanId; int: INTEGER; | |
112 | width: CARDINAL) ; | |
113 | (* Writes the value of int to cid in text form, in a field of | |
114 | the given minimum width. *) | |
115 | VAR | |
116 | s: String ; | |
117 | BEGIN | |
f5b246ce GM |
118 | s := IntegerToString (int, width, ' ', int < 0, 10, FALSE) ; |
119 | writeString (cid, s) ; | |
120 | s := KillString (s) | |
1eee94d3 GM |
121 | END WriteInt ; |
122 | ||
123 | ||
124 | PROCEDURE ReadCard (cid: IOChan.ChanId; VAR card: CARDINAL) ; | |
125 | (* Skips leading spaces, and removes any remaining characters | |
126 | from cid that form part of an unsigned whole number. The | |
127 | value of this number is assigned to card. The read result | |
128 | is set to the value allRight, outOfRange, wrongFormat, | |
129 | endOfLine, or endOfInput. | |
130 | *) | |
131 | VAR | |
132 | chClass : ScanClass ; | |
133 | nextState: ScanState ; | |
134 | ch : CHAR ; | |
135 | c : CARDINAL ; | |
136 | BEGIN | |
509eef93 | 137 | SkipSpaces (cid) ; |
1eee94d3 GM |
138 | ReadChar(cid, ch) ; |
139 | c := 0 ; | |
140 | nextState := ScanCard ; | |
141 | REPEAT | |
142 | nextState(ch, chClass, nextState) ; | |
143 | IF chClass=valid | |
144 | THEN | |
145 | IF ch='+' | |
146 | THEN | |
147 | (* ignore *) | |
148 | ELSE | |
149 | c := c*10+(ORD(ch)-ORD('0')) | |
150 | END ; | |
151 | ReadChar(cid, ch) | |
152 | ELSIF chClass=padding | |
153 | THEN | |
154 | ReadChar(cid, ch) | |
155 | END | |
156 | UNTIL (chClass=invalid) OR (chClass=terminator) ; | |
157 | IF chClass=terminator | |
158 | THEN | |
159 | card := c | |
160 | END | |
161 | END ReadCard ; | |
162 | ||
163 | ||
164 | PROCEDURE WriteCard (cid: IOChan.ChanId; card: CARDINAL; | |
165 | width: CARDINAL); | |
166 | (* Writes the value of card to cid in text form, in a field | |
167 | of the given minimum width. *) | |
168 | VAR | |
169 | s: String ; | |
170 | BEGIN | |
171 | s := CardinalToString(card, width, ' ', 10, FALSE) ; | |
172 | writeString(cid, s) ; | |
173 | s := KillString(s) | |
174 | END WriteCard ; | |
175 | ||
176 | ||
177 | END WholeIO. |