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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
//
// GENERATED FILE
//
use super::*;
use crate::SpiceContext;
use f2rust_std::*;
/// Read array of lines from a logical unit
///
/// Read lines from a Fortran logical unit and place them in a
/// character string array.
///
/// # Brief I/O
///
/// ```text
/// VARIABLE I/O DESCRIPTION
/// -------- --- --------------------------------------------------
/// UNIT I Fortran unit number to use for input.
/// MAXLIN I Maximum number of lines ARRAY can hold.
/// NUMLIN O Number of lines read from the file.
/// ARRAY O Array containing the lines read from the file.
/// EOF O Logical flag indicating the end of file.
/// ```
///
/// # Detailed Input
///
/// ```text
/// UNIT is the Fortran unit number for the input. This may
/// be either the unit number for the terminal, or the
/// unit number of a previously opened text file.
///
/// MAXLIN is the maximum number of text lines that can be placed
/// into the ARRAY.
/// ```
///
/// # Detailed Output
///
/// ```text
/// NUMLIN is the number of text lines read from the file attached
/// to UNIT and placed into ARRAY. 0 <= NUMLIN <= MAXLIN.
///
/// In the event of an error while attempting to read a line
/// from the text file attached to UNIT, NUMLIN will contain
/// the number of lines successfully read before the error
/// occurred.
///
/// ARRAY is the array which is to contain the lines of text read
/// from the text file attached to UNIT.
///
/// If an error or the end of file occurs while reading
/// from the text file attached to UNIT, this array will
/// contain the NUMLIN successfully read lines ARRAY(1)
/// through ARRAY(NUMLIN).
///
/// EOF on output, this variable will be set to .TRUE. if the
/// end of file ( IOSTAT < 0 ) is encountered during an
/// attempt to read from UNIT. Otherwise, this variable
/// will be set to .FALSE.
/// ```
///
/// # Exceptions
///
/// ```text
/// 1) If the maximum number of lines, MAXLIN, is not positive, the
/// error SPICE(INVALIDARGUMENT) is signaled.
///
/// 2) If an error occurs while attempting to read from the text file
/// attached to unit, the error is signaled by a routine in the
/// call tree of this routine.
/// ```
///
/// # Files
///
/// ```text
/// See the description of UNIT above.
/// ```
///
/// # Particulars
///
/// ```text
/// This routine reads lines of text from a file, placing each line
/// into an element of a character string array.
///
/// An end of file flag will have the value .TRUE. if the end of file
/// is reached while reading. If the file contains more lines than the
/// character string array ARRAY can hold, as specified by the
/// argument MAXLIN, the routine will return and the end of file flag
/// will have the value .FALSE., indicating that there are more lines
/// of text that may be read from the file.
///
/// Upon successful completion, the variable NUMLIN will contain the
/// number of lines of text placed into the character string array.
/// This value may be zero.
/// ```
///
/// # Examples
///
/// ```text
/// For the examples which follow, assume that we have a file named
/// 'mary.txt' which contains the following lines of text:
///
/// <BOF>
/// Mary had a little lamb
/// Whose fleece was white as snow
/// And every where that Mary went
/// The lamb was sure to go
/// <EOF>
///
/// where
///
/// <BOF> marks the beginning of the file
/// <EOF> marks the end of the file
///
/// For each example, assume that we have opened the file 'mary.txt',
/// obtaining the Fortran logical unit TXTLUN, and that we are
/// positioned to begin reading at the beginning of the file, '<BOF>'.
///
/// For brevity, none of the examples perform any error handling
/// functions: they simply assume that everything will work.
///
/// Example 1: ARRAY is large enough to contain the entire contents of
/// the file.
///
/// CHARACTER*(80) ARRAY(10)
///
/// INTEGER NUMLIN
///
/// LOGICAL EOF
///
/// CALL READLA ( TXTLUN, 10, NUMLIN, ARRAY, EOF )
///
/// At this point the output variables NUMLIN, ARRAY, and EOF have
/// the following values:
///
/// NUMLIN = 4
///
/// ARRAY(1) = 'Mary had a little lamb'
/// ARRAY(2) = 'Whose fleece was white as snow'
/// ARRAY(3) = 'And every where that Mary went'
/// ARRAY(4) = 'The lamb was sure to go'
///
/// EOF = .TRUE.
///
/// Example 2: ARRAY is not large enough to contain the entire
/// contents of the file -- perform multiple reads.
///
/// CHARACTER*(80) ARRAY(3)
///
/// INTEGER NUMLIN
///
/// LOGICAL EOF
///
/// EOF = .FALSE.
/// DO WHILE ( .NOT. EOF )
///
/// CALL READLA ( TXTLUN, 3, NUMLIN, ARRAY, EOF )
///
/// END DO
///
/// Because the line buffer ARRAY may contain at most 3 lines and the
/// file contains 4 lines, the loop calling READLA will be executed
/// twice, terminating after the second call because EOF will be
/// true.
///
/// After the first call to READLA the output variables NUMLIN, ARRAY,
/// and EOF have the following values:
///
/// NUMLIN = 3
///
/// ARRAY(1) = 'Mary had a little lamb'
/// ARRAY(2) = 'Whose fleece was white as snow'
/// ARRAY(3) = 'And every where that Mary went'
///
/// EOF = .FALSE.
///
/// After the second call to READLA the output variables NUMLIN,
/// ARRAY, and EOF have the following values:
///
/// NUMLIN = 1
///
/// ARRAY(1) = 'The lamb was sure to go'
///
/// EOF = .TRUE.
/// ```
///
/// # Author and Institution
///
/// ```text
/// J. Diaz del Rio (ODC Space)
/// K.R. Gehringer (JPL)
/// ```
///
/// # Version
///
/// ```text
/// - SPICELIB Version 1.1.0, 26-OCT-2021 (JDR)
///
/// Added IMPLICIT NONE statement.
///
/// Edited the header to comply with NAIF standard. Moved $Version
/// history entries for relevant Beta versions to $Revisions
/// section.
///
/// - SPICELIB Version 1.0.0, 20-DEC-1995 (KRG)
/// ```
///
/// # Revisions
///
/// ```text
/// - Beta Version 2.0.0, 05-JAN-1995 (KRG)
///
/// This routine now participates fully with the SPICELIB error
/// handler, checking in on entry and checking out on exit. The
/// overhead associated with the error handler should not be
/// significant relative to the operation of this routine.
///
/// Moved the test for the end of file outside of the loop. There
/// is no need to test for it every time in the loop, because we
/// only do it to decrement the number of lines read by one to
/// account for the pre-increment before the READ that set the end
/// of file.
///
/// Added a local variable MYEOF so that a value of the variable
/// EOF does not affect the termination of the read loop.
/// ```
pub fn readla(
ctx: &mut SpiceContext,
unit: i32,
maxlin: i32,
numlin: &mut i32,
array: CharArrayMut,
eof: &mut bool,
) -> crate::Result<()> {
READLA(unit, maxlin, numlin, array, eof, ctx.raw_context())?;
ctx.handle_errors()?;
Ok(())
}
//$Procedure READLA ( Read array of lines from a logical unit )
pub fn READLA(
UNIT: i32,
MAXLIN: i32,
NUMLIN: &mut i32,
ARRAY: CharArrayMut,
EOF: &mut bool,
ctx: &mut Context,
) -> f2rust_std::Result<()> {
let mut ARRAY = DummyCharArrayMut::new(ARRAY, None, 1..);
let mut I: i32 = 0;
let mut MYEOF: bool = false;
//
// SPICELIB Functions
//
//
// Local variables
//
//
// Standard SPICE error handling.
//
if RETURN(ctx) {
return Ok(());
} else {
CHKIN(b"READLA", ctx)?;
}
//
// Check to see if the maximum number of lines is positive.
//
if (MAXLIN <= 0) {
SETMSG(
b"The maximum number of lines for the output line array was not positive. It was: #.",
ctx,
);
ERRINT(b"#", MAXLIN, ctx);
SIGERR(b"SPICE(INVALIDARGUMENT)", ctx)?;
CHKOUT(b"READLA", ctx)?;
return Ok(());
}
//
// Begin reading in the lines from the text file attached to UNIT.
// Stop when the array of lines is full, I = MAXLIN, or we hit the
// end of file.
//
MYEOF = false;
*NUMLIN = 0;
I = 1;
while ((I <= MAXLIN) && !MYEOF) {
READLN(UNIT, &mut ARRAY[I], &mut MYEOF, ctx)?;
if FAILED(ctx) {
//
// If the read failed, an appropriate error message has already
// been set, so we need to set the number of lines that have
// been correctly read from the file and return.
//
CHKOUT(b"READLA", ctx)?;
return Ok(());
}
*NUMLIN = I;
I = (I + 1);
}
//
// If we got to here, then we have either filled up the line buffer
// or we reached the end of the file. If we reached the end of the
// file we need to adjust the value of NUMLIN to remove the last read
// attempt.
//
if MYEOF {
*NUMLIN = (*NUMLIN - 1);
}
*EOF = MYEOF;
CHKOUT(b"READLA", ctx)?;
Ok(())
}