]>
Commit | Line | Data |
---|---|---|
1eee94d3 GM |
1 | (* ShortWholeIO.mod implements input/output of SHORTINT/SHORTCARD over channels. |
2 | ||
83ffe9cd | 3 | Copyright (C) 2013-2023 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 ShortWholeIO ; | |
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 ; | |
36 | ||
37 | ||
38 | (* Input and output of whole numbers in decimal text form | |
39 | over specified channels. The read result is of the | |
40 | type IOConsts.ReadResults. | |
41 | *) | |
42 | ||
43 | IMPORT IOChan; | |
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: SHORTINT) ; | |
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 : SHORTCARD ; | |
63 | ch : CHAR ; | |
64 | negative : BOOLEAN ; | |
65 | BEGIN | |
66 | ReadChar(cid, ch) ; | |
67 | negative := FALSE ; | |
68 | c := 0 ; | |
69 | nextState := ScanInt ; | |
70 | REPEAT | |
71 | nextState(ch, chClass, nextState) ; | |
72 | IF chClass=valid | |
73 | THEN | |
74 | IF ch='+' | |
75 | THEN | |
76 | (* ignore *) | |
77 | ELSIF ch='-' | |
78 | THEN | |
79 | negative := NOT negative | |
80 | ELSE | |
81 | c := c*10+VAL(SHORTCARD, ORD(ch)-ORD('0')) | |
82 | END ; | |
83 | ReadChar(cid, ch) | |
84 | ELSIF chClass=padding | |
85 | THEN | |
86 | ReadChar(cid, ch) | |
87 | END | |
88 | UNTIL (chClass=invalid) OR (chClass=terminator) ; | |
89 | IF chClass=terminator | |
90 | THEN | |
91 | IF negative | |
92 | THEN | |
93 | IF c=VAL(SHORTCARD, MAX(SHORTINT))+1 | |
94 | THEN | |
95 | int := MIN(SHORTINT) | |
96 | ELSIF c<=VAL(SHORTCARD, MAX(SHORTINT)) | |
97 | THEN | |
98 | int := -VAL(SHORTINT, c) | |
99 | ELSE | |
100 | (* overflow *) | |
101 | IOChan.SetReadResult(cid, outOfRange) | |
102 | END | |
103 | ELSE | |
104 | int := c | |
105 | END | |
106 | END | |
107 | END ReadInt ; | |
108 | ||
109 | ||
110 | PROCEDURE WriteInt (cid: IOChan.ChanId; int: SHORTINT; | |
111 | width: CARDINAL) ; | |
112 | (* Writes the value of int to cid in text form, in a field of | |
113 | the given minimum width. *) | |
114 | VAR | |
115 | s: String ; | |
116 | BEGIN | |
117 | s := IntegerToString(int, width, ' ', TRUE, 10, FALSE) ; | |
118 | writeString(cid, s) ; | |
119 | s := KillString(s) | |
120 | END WriteInt ; | |
121 | ||
122 | ||
123 | PROCEDURE ReadCard (cid: IOChan.ChanId; VAR card: SHORTCARD) ; | |
124 | (* Skips leading spaces, and removes any remaining characters | |
125 | from cid that form part of an unsigned whole number. The | |
126 | value of this number is assigned to card. The read result | |
127 | is set to the value allRight, outOfRange, wrongFormat, | |
128 | endOfLine, or endOfInput. | |
129 | *) | |
130 | VAR | |
131 | chClass : ScanClass ; | |
132 | nextState: ScanState ; | |
133 | ch : CHAR ; | |
134 | c : SHORTCARD ; | |
135 | BEGIN | |
136 | ReadChar(cid, ch) ; | |
137 | c := 0 ; | |
138 | nextState := ScanCard ; | |
139 | REPEAT | |
140 | nextState(ch, chClass, nextState) ; | |
141 | IF chClass=valid | |
142 | THEN | |
143 | IF ch='+' | |
144 | THEN | |
145 | (* ignore *) | |
146 | ELSE | |
147 | c := c*10+VAL(SHORTCARD, ORD(ch)-ORD('0')) | |
148 | END ; | |
149 | ReadChar(cid, ch) | |
150 | ELSIF chClass=padding | |
151 | THEN | |
152 | ReadChar(cid, ch) | |
153 | END | |
154 | UNTIL (chClass=invalid) OR (chClass=terminator) ; | |
155 | IF chClass=terminator | |
156 | THEN | |
157 | card := c | |
158 | END | |
159 | END ReadCard ; | |
160 | ||
161 | ||
162 | PROCEDURE WriteCard (cid: IOChan.ChanId; card: SHORTCARD; | |
163 | width: CARDINAL); | |
164 | (* Writes the value of card to cid in text form, in a field | |
165 | of the given minimum width. *) | |
166 | VAR | |
167 | s: String ; | |
168 | BEGIN | |
169 | s := CardinalToString(card, width, ' ', 10, FALSE) ; | |
170 | writeString(cid, s) ; | |
171 | s := KillString(s) | |
172 | END WriteCard ; | |
173 | ||
174 | ||
175 | END ShortWholeIO. |