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
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
//
// GENERATED FILE
//
use super::*;
use crate::SpiceContext;
use f2rust_std::*;
/// Extract Double Precision Values From A String
///
/// Locate a keyword and succeeding numeric words within a string.
/// Parse and store the numeric words. Remove the keyword and
/// numeric words from the input string.
///
/// # Brief I/O
///
/// ```text
/// VARIABLE I/O DESCRIPTION
/// -------- --- --------------------------------------------------
/// KEYWD I Keyword used to mark start of a set of numbers.
/// MAXWDS I Maximum number of numeric words that can be parsed
/// STRING I-O String potentially containing KEYWD and numbers.
/// NFOUND O Number of numeric words found following the KEYWD.
/// PARSED O Number of numeric words translated and returned.
/// VALUES O The double precision values for the numbers.
/// ```
///
/// # Detailed Input
///
/// ```text
/// KEYWD is a word used to mark the start of a set of numeric
/// words of interest.
///
/// MAXWDS is the maximum number of numeric words that can be
/// parsed and returned.
///
/// STRING is a string potentially containing KEYWD and numbers.
/// ```
///
/// # Detailed Output
///
/// ```text
/// STRING is the input string stripped of all parsed
/// numeric words. If there was room available to parse
/// all of the numeric words associated with KEYWD, the
/// keyword that marked the beginning of the parsed
/// numbers in the original string will also be removed.
///
/// NFOUND is the number of numeric words that were found
/// following KEYWD but preceding the next non-numeric
/// word of the string. If the KEYWD is not present in
/// the string, NFOUND is returned as -1. If the keyword
/// is located but the next word in the string is
/// non-numeric NFOUND will be returned as 0.
///
/// PARSED is the number of numeric words that were actually
/// parsed and stored in the output array VALUES. If no
/// values are parsed PARSED is returned as 0.
///
/// VALUES are the double precision values for the parsed
/// numeric words that follow the first occurrence of the
/// keyword but precede the next non-numeric word.
/// ```
///
/// # Exceptions
///
/// ```text
/// Error free.
/// ```
///
/// # Particulars
///
/// ```text
/// Definitions:
///
/// WORD is a set of consecutive non-blank characters
/// delimited by blanks or the end of the string
/// that contains them.
///
/// NUMERIC WORD a word that can be parsed by the
/// SPICELIB routine NPARSD without error. All
/// FORTRAN numeric representations are numeric
/// words. In addition 'PI', 'Pi', 'pI', and 'pi'
/// are all recognized as having the value:
///
/// 3.1415926535897932384626D0
///
/// See NPARSD FOR A a full description of
/// legitimate numeric words.
///
/// Given a string and a keyword this routine locates the first
/// occurrence of the keyword in the string and returns the double
/// precision representations of up to MAXWDS succeeding numeric
/// words. All parsed numeric words are removed from the string.
/// If every numeric word following KEYWD but preceding the next
/// non-numeric word is parsed, KEYWD will also be removed from
/// the string.
///
/// If the keyword cannot be located in the string, the variable
/// NFOUND will be returned as -1 and the string will be unchanged.
///
/// In all other cases, some part of the string (possibly all of it)
/// will be removed.
/// ```
///
/// # Examples
///
/// ```text
/// Input STRING 'LONGITUDE 39.2829 LATITUDE 24.27682'
/// KEYWD 'LONGITUDE'
/// MAXWDS 4
///
/// Output: STRING ' LATITUDE 24.27682'
/// NFOUND 1
/// PARSED 1
/// VALUES 3.92829D+01
///
///
///
/// Input STRING 'THIS IS A BAD STRING FOR NUMBERS'
/// KEYWD 'RADIUS'
/// MAXWDS 2
///
/// Output: STRING 'THIS IS A BAD STRING FOR NUMBERS'
/// NFOUND -1
/// PARSED 0
/// VALUES (unchanged)
///
///
///
/// Input STRING 'PRIMES 11 13 17 19 23 NON-PRIMES 12 14 15'
/// KEYWD 'PRIMES'
/// MAXWDS 3
///
/// Output: STRING 'PRIMES 19 23 NON-PRIMES 12 14 15'
/// NFOUND 5
/// PARSED 3
/// VALUES 1.1D+01
/// 1.3D+01
/// 1.7D+01
///
/// Input STRING 'PRIMES 11 13 17 19 23 NON-PRIMES 12 14 15'
/// KEYWD 'PRIMES'
/// MAXWDS 5
///
/// Output: STRING ' NON-PRIMES 12 14 15'
/// NFOUND 5
/// PARSED 5
/// VALUES 1.1D+01
/// 1.3D+01
/// 1.7D+01
/// 1.9D+01
/// 2.3D+01
/// ```
///
/// # Author and Institution
///
/// ```text
/// J. Diaz del Rio (ODC Space)
/// H.A. Neilan (JPL)
/// W.L. Taber (JPL)
/// I.M. Underwood (JPL)
/// ```
///
/// # Version
///
/// ```text
/// - SPICELIB Version 1.2.0, 05-JUN-2021 (JDR)
///
/// Added IMPLICIT NONE statement.
///
/// Edited the header to comply with NAIF standard.
///
/// - SPICELIB Version 1.1.1, 10-MAR-1992 (WLT)
///
/// Comment section for permuted index source lines was added
/// following the header.
///
/// - SPICELIB Version 1.1.0, 23-MAY-1990 (HAN)
///
/// The variable FOUND was changed to NFOUND.
///
/// - SPICELIB Version 1.0.0, 31-JAN-1990 (WLT) (IMU)
/// ```
///
/// # Revisions
///
/// ```text
/// - SPICELIB Version 1.1.0, 23-MAY-1990 (HAN)
///
/// The variable FOUND was changed to NFOUND. Other SPICELIB
/// routines that use the variable FOUND declare it as a logical.
/// In order to conform to this convention, FOUND was changed to
/// NFOUND to indicate that it has an integer value, not a logical
/// value.
/// ```
pub fn dxtrct(
ctx: &mut SpiceContext,
keywd: &str,
maxwds: i32,
string: &mut str,
nfound: &mut i32,
parsed: &mut i32,
values: &mut [f64],
) {
DXTRCT(
keywd.as_bytes(),
maxwds,
fstr::StrBytes::new(string).as_mut(),
nfound,
parsed,
values,
ctx.raw_context(),
);
}
//$Procedure DXTRCT (Extract Double Precision Values From A String)
pub fn DXTRCT(
KEYWD: &[u8],
MAXWDS: i32,
STRING: &mut [u8],
NFOUND: &mut i32,
PARSED: &mut i32,
VALUES: &mut [f64],
ctx: &mut Context,
) {
let mut VALUES = DummyArrayMut::new(VALUES, 1..);
let mut LENGTH: i32 = 0;
let mut POSITN: i32 = 0;
let mut BERASE: i32 = 0;
let mut EERASE: i32 = 0;
let mut FALLBK: i32 = 0;
let mut START: i32 = 0;
let mut I: i32 = 0;
let mut J: i32 = 0;
let mut X: f64 = 0.0;
let mut ERROR = [b' '; 80];
let mut PNTR: i32 = 0;
//
// SPICELIB functions
//
//
// Local variables
//
//
// No keywords or numbers have been located yet.
//
*NFOUND = 0;
*PARSED = 0;
//
// Locate the keyword within the string and get the length of the
// string.
//
POSITN = WDINDX(STRING, KEYWD);
LENGTH = LASTNB(STRING);
if (POSITN == 0) {
*NFOUND = -1;
*PARSED = 0;
return;
}
//
// Set the begin erase marker to the start of the current word
// Set the end erase marker to the end of the current word
//
BERASE = POSITN;
EERASE = ((POSITN + NBLEN(KEYWD)) - 1);
START = (EERASE + 1);
if (START < LENGTH) {
//
// Locate the next word and try to parse it ...
//
FNDNWD(STRING, START, &mut I, &mut J);
NPARSD(
fstr::substr(STRING, I..=J),
&mut X,
&mut ERROR,
&mut PNTR,
ctx,
);
if fstr::eq(&ERROR, b" ") {
//
// ... mark its starting position as a possible starting
// point for deletion if we run out of room for parsed numbers.
//
FALLBK = I;
EERASE = J;
START = (J + 1);
*NFOUND = (*NFOUND + 1);
*PARSED = (*PARSED + 1);
VALUES[*PARSED] = X;
}
} else {
fstr::assign(fstr::substr_mut(STRING, BERASE..), b" ");
return;
}
//
// Now find all of the succeeding numeric words until we run out of
// numeric words or string to look at.
//
while ((START < LENGTH) && fstr::eq(&ERROR, b" ")) {
//
// Find the next word and try to parse it as a number.
//
FNDNWD(STRING, START, &mut I, &mut J);
NPARSD(
fstr::substr(STRING, I..=J),
&mut X,
&mut ERROR,
&mut PNTR,
ctx,
);
if fstr::eq(&ERROR, b" ") {
//
// It's a number! Congratulations!
//
*NFOUND = (*NFOUND + 1);
//
// If there is room ...
//
if (*NFOUND <= MAXWDS) {
//
// 1. Increment the counter PARSED.
// 2. Load the DP value into the output array.
// 3. Set the pointer for the end of the erase
// region to be the end of this word.
//
*PARSED = (*PARSED + 1);
VALUES[*PARSED] = X;
EERASE = J;
} else {
//
// Set the pointer of the begin erase region to be the
// the pointer set up just for this occasion.
//
BERASE = FALLBK;
}
//
// Set the place to begin looking for the next word to be
// at the first character following the end of the current
// word.
//
START = (J + 1);
}
}
//
// Remove the parsed words from the string.
//
I = BERASE;
J = (EERASE + 1);
while (J <= LENGTH) {
let val = fstr::substr(STRING, J..=J).to_vec();
fstr::assign(fstr::substr_mut(STRING, I..=I), &val);
I = (I + 1);
J = (J + 1);
}
fstr::assign(fstr::substr_mut(STRING, I..), b" ");
}