summaryrefslogtreecommitdiff
path: root/gcc/m2/gm2-libs-iso/TextIO.mod
blob: a6ca17edecb6e09f9b57514e33cb7b937a4d9e6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
(* TextIO.mod implement the ISO TextIO specification.

Copyright (C) 2008-2023 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 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
General Public License for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  *)

IMPLEMENTATION MODULE TextIO ;


IMPORT IOChan, IOConsts, CharClass, ASCII ;
FROM SYSTEM IMPORT ADR ;
FROM FIO IMPORT FlushOutErr ;
FROM libc IMPORT printf ;
FROM TextUtil IMPORT SkipSpaces, EofOrEoln, CharAvailable ;


CONST
   DebugState = FALSE ;


(*
   DumpState
*)

PROCEDURE DumpState (cid: IOChan.ChanId) ;
BEGIN
   printf ("cid = %d, ", cid) ;
   CASE IOChan.ReadResult (cid) OF

   IOConsts.notKnown:  printf ('notKnown') |
   IOConsts.allRight:  printf ('allRight') |
   IOConsts.outOfRange: printf ('outOfRange') |
   IOConsts.wrongFormat: printf ('wrongFormat') |
   IOConsts.endOfLine: printf ('endOfLine') |
   IOConsts.endOfInput: printf ('endOfInput')

   END ;
   printf ("\n")
END DumpState ;


(*
   SetNul - assigns the result in cid.
               If s is empty then leave as endOfInput
                  or endOfLine
               If s is not empty then assign allRight
               If range and i exceeds, h, then assign outOfRange
*)

PROCEDURE SetNul (cid: IOChan.ChanId; i: CARDINAL;
                     VAR s: ARRAY OF CHAR; range: BOOLEAN) ;
BEGIN
   IF DebugState
   THEN
      DumpState (cid)
   END ;
   IF i<=HIGH(s)
   THEN
      s[i] := ASCII.nul
   ELSIF range
   THEN
      IOChan.SetReadResult (cid, IOConsts.outOfRange)
   END
END SetNul ;


PROCEDURE ReadChar (cid: IOChan.ChanId; VAR ch: CHAR);
  (* If possible, removes a character from the input stream
     cid and assigns the corresponding value to ch.  The
     read result is set to the value allRight, endOfLine, or
     endOfInput.
  *)
VAR
   res: IOConsts.ReadResults ;
BEGIN
   FlushOutErr ;
   IF CharAvailable (cid)
   THEN
      IOChan.Look (cid, ch, res) ;
      IF res = IOConsts.allRight
      THEN
         IOChan.Skip (cid)
      END
   END
END ReadChar ;


PROCEDURE ReadRestLine (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Removes any remaining characters from the input stream
     cid before the next line mark,  copying to s as many as
     can be accommodated as a string value.  The read result is
     set to the value allRight, outOfRange, endOfLine, or
     endOfInput.
  *)
VAR
   i, h    : CARDINAL ;
   finished: BOOLEAN ;
BEGIN
   h := HIGH(s) ;
   i := 0 ;
   finished := FALSE ;
   WHILE (i<=h) AND CharAvailable (cid) AND (NOT finished) DO
      ReadChar (cid, s[i]) ;
      IF EofOrEoln (cid)
      THEN
         finished := TRUE
      ELSE
         INC (i)
      END
   END ;
   WHILE CharAvailable (cid) DO
      IOChan.Skip (cid)
   END ;
   SetNul (cid, i, s, TRUE)
END ReadRestLine ;


PROCEDURE ReadString (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Removes only those characters from the input stream cid
     before the next line mark that can be accommodated in s
     as a string value, and copies them to s.  The read result
     is set to the value allRight, endOfLine, or endOfInput.
  *)
VAR
   i, h    : CARDINAL ;
   finished: BOOLEAN ;
BEGIN
   h := HIGH (s) ;
   i := 0 ;
   finished := FALSE ;
   WHILE (i<=h) AND CharAvailable (cid) AND (NOT finished) DO
      ReadChar (cid, s[i]) ;
      IF EofOrEoln (cid)
      THEN
         finished := TRUE
      ELSE
         INC (i)
      END
   END ;
   SetNul (cid, i, s, FALSE)
END ReadString ;


PROCEDURE ReadToken (cid: IOChan.ChanId; VAR s: ARRAY OF CHAR);
  (* Skips leading spaces, and then removes characters from
     the input stream cid before the next space or line mark,
     copying to s as many as can be accommodated as a string
     value.  The read result is set to the value allRight,
     outOfRange, endOfLine, or endOfInput.
  *)
VAR
   i, h: CARDINAL ;
BEGIN
   SkipSpaces (cid) ;
   h := HIGH (s) ;
   i := 0 ;
   WHILE (i<=h) AND CharAvailable (cid) DO
      ReadChar (cid, s[i]) ;
      IF (s[i]=ASCII.nul) OR CharClass.IsWhiteSpace (s[i])
      THEN
         SetNul (cid, i, s, TRUE) ;
         RETURN
      END ;
      INC (i)
   END ;
   SetNul (cid, i, s, TRUE)
END ReadToken ;

  (* The following procedure reads past the next line mark *)

PROCEDURE SkipLine (cid: IOChan.ChanId);
  (* Removes successive items from the input stream cid up
     to and including the next line mark, or until the end
     of input is reached.  The read result is set to the
     value allRight, or endOfInput.
  *)
VAR
   ch : CHAR ;
   res: IOConsts.ReadResults ;
BEGIN
   IOChan.Look (cid, ch, res) ;
   WHILE res = IOConsts.allRight DO
      IOChan.SkipLook (cid, ch, res)
   END ;
   IF res = IOConsts.endOfLine
   THEN
      IOChan.Skip (cid) ;
      IOChan.SetReadResult (cid, IOConsts.allRight)
   END
END SkipLine ;

  (* Output procedures *)

PROCEDURE WriteChar (cid: IOChan.ChanId; ch: CHAR);
  (* Writes the value of ch to the output stream cid. *)
BEGIN
   IOChan.TextWrite (cid, ADR (ch), SIZE (ch))
END WriteChar ;

PROCEDURE WriteLn (cid: IOChan.ChanId);
  (* Writes a line mark to the output stream cid. *)
BEGIN
   IOChan.WriteLn (cid)
END WriteLn ;

PROCEDURE WriteString (cid: IOChan.ChanId; s: ARRAY OF CHAR);
  (* Writes the string value in s to the output stream cid. *)
BEGIN
   IOChan.TextWrite (cid, ADR (s), LENGTH (s))
END WriteString ;


END TextIO.