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
//
// GENERATED FILE
//
use super::*;
use f2rust_std::*;
const EOLTSZ: i32 = 5;
//$Procedure ZZASCII ( determine/verify EOL terminators in a text file )
pub fn ZZASCII(
FILE: &[u8],
LINE: &mut [u8],
CHECK: bool,
TERMIN: &mut [u8],
ctx: &mut Context,
) -> f2rust_std::Result<()> {
let mut NATIVE = [b' '; EOLTSZ as usize];
let mut DOSCNT: i32 = 0;
let mut I: i32 = 0;
let mut IOSTAT: i32 = 0;
let mut MACCNT: i32 = 0;
let mut NUMBER: i32 = 0;
let mut RECLEN: i32 = 0;
let mut UNXCNT: i32 = 0;
//
// SPICELIB functions.
//
//
// Local parameters.
//
//
// Local variables.
//
//
// Discovery check-in. Can't determine the terminator in RETURN
// mode.
//
if RETURN(ctx) {
fstr::assign(TERMIN, b"?");
return Ok(());
}
//
// Check-in to the error system.
//
CHKIN(b"ZZASCII", ctx)?;
//
// Retrieve the native line terminator.
//
ZZPLATFM(b"TEXT_FORMAT", &mut NATIVE, ctx);
//
// If it is VAX, return immediately with undefined terminator.
//
if EQSTR(&NATIVE, b"VAX") {
fstr::assign(TERMIN, b"?");
CHKOUT(b"ZZASCII", ctx)?;
return Ok(());
}
//
// Set the record length that will be used to read data from
// the file.
//
RECLEN = intrinsics::LEN(LINE);
//
// Check the length of the work string is sufficient to perform the
// operations. Less than 3 is a no-op.
//
if (intrinsics::LEN(LINE) < 3) {
fstr::assign(TERMIN, b"?");
SETMSG(
b"Work string lacks sufficient length to perform operation.",
ctx,
);
SIGERR(b"SPICE(STRINGTOOSHORT)", ctx)?;
CHKOUT(b"ZZASCII", ctx)?;
return Ok(());
}
//
// Find a free logical unit for file access.
//
GETLUN(&mut NUMBER, ctx)?;
//
// Open the file for DIRECT access.
//
{
use f2rust_std::io;
let specs = io::OpenSpecs {
unit: Some(NUMBER),
file: Some(fstr::substr(FILE, 1..=RTRIM(FILE))),
access: Some(b"DIRECT"),
status: Some(b"OLD"),
recl: Some(RECLEN),
..Default::default()
};
IOSTAT = io::capture_iostat(|| ctx.open(specs))?;
}
if (IOSTAT != 0) {
//
// The open failed, can't determine the terminator if the routine
// can't open the file.
//
fstr::assign(TERMIN, b"?");
//
// Execute a close, J.I.C.
//
{
use f2rust_std::io;
let specs = io::CloseSpecs {
unit: Some(NUMBER),
..Default::default()
};
ctx.close(specs)?;
}
SETMSG(b"File open failed for file \'$1\'. IOSTAT value $2.", ctx);
ERRCH(b"$1", FILE, ctx);
ERRINT(b"$2", IOSTAT, ctx);
SIGERR(b"SPICE(FILEOPENFAIL)", ctx)?;
CHKOUT(b"ZZASCII", ctx)?;
return Ok(());
}
//
// Read a line into the LINE variable assigned by the user.
//
fstr::assign(LINE, b" ");
{
use f2rust_std::{
data::Val,
io::{self, Reader},
};
let mut reader = io::UnformattedReader::new(ctx.io_unit(NUMBER)?, Some(1))?;
IOSTAT = io::capture_iostat(|| {
reader.start()?;
reader.read_str(LINE)?;
reader.finish()?;
Ok(())
})?;
}
if (IOSTAT != 0) {
//
// If something went wrong during this read, a part or the whole
// returned line may contain garbage. Instead of examining it and
// making wrong determination based on it, set terminator to
// undefined and return.
//
fstr::assign(TERMIN, b"?");
//
// Execute a close, J.I.C.
//
{
use f2rust_std::io;
let specs = io::CloseSpecs {
unit: Some(NUMBER),
..Default::default()
};
ctx.close(specs)?;
}
CHKOUT(b"ZZASCII", ctx)?;
return Ok(());
}
//
// We have a line of text data. Use ICHAR to scan for carriage
// returns and line feeds and count how may of various recognized
// line termination sequences are in this line.
//
DOSCNT = 0;
UNXCNT = 0;
MACCNT = 0;
I = 1;
while (I < intrinsics::LEN(LINE)) {
//
// Check for ICHAR values of 10 (LF) and 13 (CR).
//
if (intrinsics::ICHAR(fstr::substr(LINE, I..=I)) == 10) {
//
// Found a UNIX line terminator LF.
//
UNXCNT = (UNXCNT + 1);
} else if (intrinsics::ICHAR(fstr::substr(LINE, I..=I)) == 13) {
//
// Found CR, increment character counter and check
// the next character.
//
I = (I + 1);
if (intrinsics::ICHAR(fstr::substr(LINE, I..=I)) == 10) {
//
// Found a DOS line terminator CR+LF.
//
DOSCNT = (DOSCNT + 1);
} else {
//
// Found a Classic Mac line terminator CR.
//
MACCNT = (MACCNT + 1);
}
}
I = (I + 1);
}
//
// Examine the counters.
//
if (((DOSCNT > 0) && (UNXCNT == 0)) && (MACCNT == 0)) {
//
// Only DOS terminator counter is non-zero. ID the file as DOS.
//
fstr::assign(TERMIN, b"CR-LF");
} else if (((DOSCNT == 0) && (UNXCNT > 0)) && (MACCNT == 0)) {
//
// Only Unix terminator counter is non-zero. ID the file as UNIX.
//
fstr::assign(TERMIN, b"LF");
} else if (((DOSCNT == 0) && (UNXCNT == 0)) && (MACCNT > 0)) {
//
// Only Mac terminator counter is non-zero. ID the file as Mac
// Classic.
//
fstr::assign(TERMIN, b"CR");
} else {
//
// We can get here in two cases. First if the line did not
// contain any CRs or LFs. Second if the line contained more than
// one kind of terminators. In either case the format of the file
// is unclear.
//
fstr::assign(TERMIN, b"?");
}
//
// Close the file.
//
{
use f2rust_std::io;
let specs = io::CloseSpecs {
unit: Some(NUMBER),
..Default::default()
};
ctx.close(specs)?;
}
//
// If we were told check the terminator against the native one, do
// it.
//
if CHECK {
//
// If the terminator was identified and does not match the native
// one, error out.
//
if (!EQSTR(TERMIN, &NATIVE) && !EQSTR(TERMIN, b"?")) {
SETMSG(b"Text file \'$1\' contains lines terminated with \'$2\' while the expected terminator for this platform is \'$3\'. SPICE cannot process the file in the current form. This problem likely occurred because the file was copied in binary mode between operating systems where the operating systems use different text line terminators. Try converting the file to native text form using a utility such as dos2unix or unix2dos.", ctx);
ERRCH(b"$1", FILE, ctx);
ERRCH(b"$2", TERMIN, ctx);
ERRCH(b"$3", &NATIVE, ctx);
SIGERR(b"SPICE(INCOMPATIBLEEOL)", ctx)?;
CHKOUT(b"ZZASCII", ctx)?;
return Ok(());
}
}
CHKOUT(b"ZZASCII", ctx)?;
Ok(())
}