SDDSlib
Loading...
Searching...
No Matches
data_scan.c File Reference

Provides functions for scanning and parsing free-format data. More...

#include "mdb.h"
#include <ctype.h>

Go to the source code of this file.

Macros

#define float_start(m_c)
 
#define int_start(m_c)
 
#define skip_it(m_c)
 
#define nskip_it(m_c)
 

Functions

int get_double (double *dptr, char *s)
 Parses a double value from the given string.
 
int get_longdouble (long double *dptr, char *s)
 Parses a long double value from the given string.
 
int get_double1 (double *dptr, char *s)
 Parses a double value from the given string without modifying the string.
 
int get_double1_old (double *dptr, char *s)
 
int get_float (float *fptr, char *s)
 Parses a float value from the given string.
 
int get_long (long *iptr, char *s)
 Parses a long integer value from the given string.
 
int get_long1 (long *lptr, char *s)
 Parses a long integer value from the given string without modifying the string.
 
int get_long1_old (long *iptr, char *s)
 
int get_short (short *iptr, char *s)
 Parses a short integer value from the given string.
 
int get_int (int *iptr, char *s)
 Parses an integer value from the given string.
 
char * get_token (char *s)
 Extracts the next token from the input string.
 
char * get_token_buf (char *s, char *buf, long lbuf)
 Extracts the next token from the input string into a provided buffer.
 
long tokenIsInteger (char *token)
 Checks if the given token represents a valid integer.
 
long tokenIsNumber (char *token)
 Checks if the given token represents a valid number.
 

Detailed Description

Provides functions for scanning and parsing free-format data.

This file contains functions such as get_double(), get_float(), get_long(), get_token(), and get_token_buf() to facilitate easy scanning and parsing of numerical and token-based data from strings.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file data_scan.c.

Macro Definition Documentation

◆ float_start

#define float_start ( m_c)
Value:
(isdigit(*(m_c)) || *(m_c) == '.' || ((*(m_c) == '-' || *(m_c) == '+') && (isdigit(*((m_c) + 1)) || *((m_c) + 1) == '.')))

Definition at line 23 of file data_scan.c.

◆ int_start

#define int_start ( m_c)
Value:
(isdigit(*(m_c)) || ((*(m_c) == '-' || *(m_c) == '+') && isdigit(*((m_c) + 1))))

Definition at line 24 of file data_scan.c.

◆ nskip_it

#define nskip_it ( m_c)
Value:
(!isspace(m_c) && (m_c) != ',' && (m_c) != ';')

Definition at line 27 of file data_scan.c.

◆ skip_it

#define skip_it ( m_c)
Value:
(isspace(m_c) || (m_c) == ',' || (m_c) == ';')

Definition at line 26 of file data_scan.c.

Function Documentation

◆ get_double()

int get_double ( double * dptr,
char * s )

Parses a double value from the given string.

This function scans the input string for a valid double-precision floating-point number, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]dptrPointer to store the parsed double value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if a double was successfully parsed, 0 otherwise.

Definition at line 40 of file data_scan.c.

40 {
41 register char *ptr0;
42 register int was_point = 0;
43
44 /* skip leading non-number characters */
45 ptr0 = s;
46 while (!float_start(s) && *s)
47 s++;
48 if (*s == 0)
49 return (0);
50
51 /* scan the number */
52 sscanf(s, "%lf", dptr);
53
54 /* skip to first white-space following number */
55
56 /* skip sign, if any */
57 if (*s == '-' || *s == '+')
58 s++;
59
60 /* skip mantissa */
61 while (isdigit(*s) || (*s == '.' && !was_point))
62 if (*s++ == '.')
63 was_point = 1;
64
65 if (*s == 'e' || *s == 'E') { /* skip exponent, if any */
66 s++;
67 if (*s == '+' || *s == '-')
68 s++;
69 while (isdigit(*s))
70 s++;
71 }
72
73 strcpy_ss(ptr0, s);
74 return (1);
75}
char * strcpy_ss(char *dest, const char *src)
Safely copies a string, handling memory overlap.
Definition str_copy.c:34

◆ get_double1()

int get_double1 ( double * dptr,
char * s )

Parses a double value from the given string without modifying the string.

This function scans the input string for a valid double-precision floating-point number, stores the result in the provided pointer, and ensures that the string remains unchanged after parsing.

Parameters
[out]dptrPointer to store the parsed double value.
[in]sInput string to scan. It remains unchanged after parsing.
Returns
Returns 1 if a double was successfully parsed, 0 otherwise.

Definition at line 133 of file data_scan.c.

133 {
134 char *endptr;
135 double val;
136
137 if (s == NULL || *s == '\0')
138 return 0;
139
140 // Remove trailing whitespace
141 char *p = s + strlen(s) - 1;
142 while (p >= s && isspace((unsigned char)*p))
143 p--;
144 *(p + 1) = '\0';
145
146 // Start from the beginning and try to find a number that ends at the end of the string
147 char *start = s;
148 while (*start) {
149 val = strtod(start, &endptr);
150
151 if (endptr != start) {
152 // Check if we've reached the end of the string
153 if (*endptr == '\0') {
154 *dptr = val;
155 return 1;
156 }
157 }
158 start++;
159 }
160 return 0;
161}

◆ get_double1_old()

int get_double1_old ( double * dptr,
char * s )

Definition at line 163 of file data_scan.c.

163 {
164 register int was_point = 0;
165
166 /* skip leading non-number characters */
167 while (!float_start(s) && *s)
168 s++;
169 if (*s == 0)
170 return (0);
171
172 /* scan the number */
173 sscanf(s, "%lf", dptr);
174
175 /* skip to first white-space following number */
176
177 /* skip sign, if any */
178 if (*s == '-' || *s == '+')
179 s++;
180
181 /* skip mantissa */
182 while (isdigit(*s) || (*s == '.' && !was_point))
183 if (*s++ == '.')
184 was_point = 1;
185
186 if (*s == 'e' || *s == 'E') { /* skip exponent, if any */
187 s++;
188 if (*s == '+' || *s == '-')
189 s++;
190 while (isdigit(*s))
191 s++;
192 }
193
194 return (1);
195}

◆ get_float()

int get_float ( float * fptr,
char * s )

Parses a float value from the given string.

This function scans the input string for a valid single-precision floating-point number, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]fptrPointer to store the parsed float value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if a float was successfully parsed, 0 otherwise.

Definition at line 208 of file data_scan.c.

208 {
209 register char *ptr0;
210 register int was_point = 0;
211
212 /* skip leading non-number characters */
213 ptr0 = s;
214 while (!float_start(s) && *s)
215 s++;
216 if (*s == 0)
217 return (0);
218
219 /* scan the number */
220 sscanf(s, "%f", fptr);
221
222 /* skip to first white-space following number */
223
224 /* skip sign, if any */
225 if (*s == '-' || *s == '+')
226 s++;
227
228 /* skip mantissa */
229 while (isdigit(*s) || (*s == '.' && !was_point))
230 if (*s++ == '.')
231 was_point = 1;
232
233 if (*s == 'e' || *s == 'E') { /* skip exponent, if any */
234 s++;
235 if (*s == '+' || *s == '-')
236 s++;
237 while (isdigit(*s))
238 s++;
239 }
240
241 strcpy_ss(ptr0, s);
242 return (1);
243}

◆ get_int()

int get_int ( int * iptr,
char * s )

Parses an integer value from the given string.

This function scans the input string for a valid integer, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]iptrPointer to store the parsed integer value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if an integer was successfully parsed, 0 otherwise.

Definition at line 380 of file data_scan.c.

380 {
381 char *ptr0;
382
383 /* skip leading white-space and commas */
384 ptr0 = s;
385 while (!int_start(s) && *s)
386 s++;
387 if (*s == 0)
388 return (0);
389
390 /* scan the number */
391 sscanf(s, "%d", iptr);
392
393 /* skip to first white-space following number */
394 if (*s == '-' || *s == '+')
395 s++;
396 while (isdigit(*s))
397 s++;
398
399 strcpy_ss(ptr0, s);
400 return (1);
401}

◆ get_long()

int get_long ( long * iptr,
char * s )

Parses a long integer value from the given string.

This function scans the input string for a valid long integer, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]iptrPointer to store the parsed long integer value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if a long integer was successfully parsed, 0 otherwise.

Definition at line 255 of file data_scan.c.

255 {
256 char *ptr0;
257
258 /* skip leading white-space and commas */
259 ptr0 = s;
260 while (!int_start(s) && *s)
261 s++;
262 if (*s == 0)
263 return (0);
264
265 /* scan the number */
266 sscanf(s, "%ld", iptr);
267
268 /* skip to first white-space following number */
269 if (*s == '-' || *s == '+')
270 s++;
271 while (isdigit(*s))
272 s++;
273
274 strcpy_ss(ptr0, s);
275 return (1);
276}

◆ get_long1()

int get_long1 ( long * lptr,
char * s )

Parses a long integer value from the given string without modifying the string.

This function scans the input string for a valid long integer, stores the result in the provided pointer, and ensures that the string remains unchanged after parsing.

Parameters
[out]lptrPointer to store the parsed long integer value.
[in]sInput string to scan. It remains unchanged after parsing.
Returns
Returns 1 if a long integer was successfully parsed, 0 otherwise.

Definition at line 288 of file data_scan.c.

288 {
289 char *endptr;
290 long val;
291
292 if (s == NULL || *s == '\0')
293 return 0;
294
295 // Remove trailing whitespace
296 char *p = s + strlen(s) - 1;
297 while (p >= s && isspace((unsigned char)*p))
298 p--;
299 *(p + 1) = '\0';
300
301 // Start from the beginning and try to find a number that ends at the end of the string
302 char *start = s;
303 while (*start) {
304 val = strtol(start, &endptr, 10); // Base 10
305
306 if (endptr != start) {
307 // Check if we've reached the end of the string
308 if (*endptr == '\0') {
309 *lptr = val;
310 return 1;
311 }
312 }
313 start++;
314 }
315 return 0;
316}

◆ get_long1_old()

int get_long1_old ( long * iptr,
char * s )

Definition at line 318 of file data_scan.c.

318 {
319
320 /* skip leading white-space and commas */
321 while (!int_start(s) && *s)
322 s++;
323 if (*s == 0)
324 return (0);
325
326 /* scan the number */
327 sscanf(s, "%ld", iptr);
328
329 /* skip to first white-space following number */
330 if (*s == '-' || *s == '+')
331 s++;
332 while (isdigit(*s))
333 s++;
334 return (1);
335}

◆ get_longdouble()

int get_longdouble ( long double * dptr,
char * s )

Parses a long double value from the given string.

This function scans the input string for a valid long double floating-point number, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]dptrPointer to store the parsed long double value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if a long double was successfully parsed, 0 otherwise.

Definition at line 88 of file data_scan.c.

88 {
89 register char *ptr0;
90 register int was_point = 0;
91
92 /* skip leading non-number characters */
93 ptr0 = s;
94 while (!float_start(s) && *s)
95 s++;
96 if (*s == 0)
97 return (0);
98 /* scan the number */
99 sscanf(s, "%Lf", dptr);
100 /* skip to first white-space following number */
101
102 /* skip sign, if any */
103 if (*s == '-' || *s == '+')
104 s++;
105
106 /* skip mantissa */
107 while (isdigit(*s) || (*s == '.' && !was_point))
108 if (*s++ == '.')
109 was_point = 1;
110
111 if (*s == 'e' || *s == 'E') { /* skip exponent, if any */
112 s++;
113 if (*s == '+' || *s == '-')
114 s++;
115 while (isdigit(*s))
116 s++;
117 }
118 strcpy_ss(ptr0, s);
119 return (1);
120}

◆ get_short()

int get_short ( short * iptr,
char * s )

Parses a short integer value from the given string.

This function scans the input string for a valid short integer, stores the result in the provided pointer, and updates the string pointer to the position following the parsed number.

Parameters
[out]iptrPointer to store the parsed short integer value.
[in,out]sInput string to scan. It will be modified to point after the parsed number.
Returns
Returns 1 if a short integer was successfully parsed, 0 otherwise.

Definition at line 347 of file data_scan.c.

347 {
348 char *ptr0;
349
350 /* skip leading white-space and commas */
351 ptr0 = s;
352 while (!int_start(s) && *s)
353 s++;
354 if (*s == 0)
355 return (0);
356
357 /* scan the number */
358 sscanf(s, "%hd", iptr);
359
360 /* skip to first white-space following number */
361 if (*s == '-' || *s == '+')
362 s++;
363 while (isdigit(*s))
364 s++;
365
366 strcpy_ss(ptr0, s);
367 return (1);
368}

◆ get_token()

char * get_token ( char * s)

Extracts the next token from the input string.

This function scans the input string for the next token, which can be a quoted string or a sequence of non-separator characters. It allocates memory for the token, copies it to the allocated space, and updates the input string pointer to the position following the token.

Parameters
[in,out]sInput string to scan. It will be modified to point after the extracted token.
Returns
Returns a pointer to the newly allocated token string, or NULL if no token is found.

Definition at line 413 of file data_scan.c.

413 {
414 char *ptr0, *ptr1, *ptr;
415
416 /* skip leading white-space and commas */
417 ptr0 = s;
418 while (skip_it(*s))
419 s++;
420 if (*s == 0)
421 return (NULL);
422 ptr1 = s;
423
424 if (*s == '"' && (ptr0 == s || *(s - 1) != '\\')) {
425 ptr1 = s + 1;
426 /* quoted string, so skip to next quotation mark */
427 do {
428 s++;
429 } while (*s && (*s != '"' || *(s - 1) == '\\'));
430 if (*s == '"' && *(s - 1) != '\\')
431 *s = ' ';
432 } else {
433 /* skip to first white-space following token */
434 do {
435 s++;
436 if (*s == '"' && *(s - 1) != '\\') {
437 while (*++s && (*s != '"' || *(s - 1) == '\\'))
438 ;
439 }
440 } while (*s && nskip_it(*s));
441 }
442
443 ptr = tmalloc((unsigned)sizeof(*ptr) * (s - ptr1 + 1));
444 strncpy(ptr, ptr1, s - ptr1);
445 ptr[s - ptr1] = 0;
446
447 strcpy_ss(ptr0, s);
448 return (ptr);
449}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59

◆ get_token_buf()

char * get_token_buf ( char * s,
char * buf,
long lbuf )

Extracts the next token from the input string into a provided buffer.

This function scans the input string for the next token, which can be a quoted string or a sequence of non-separator characters. It copies the token into the provided buffer if it fits, and updates the input string pointer to the position following the token.

Parameters
[in,out]sInput string to scan. It will be modified to point after the extracted token.
[out]bufBuffer to store the extracted token.
[in]lbufLength of the buffer to prevent overflow.
Returns
Returns a pointer to the buffer containing the token, or NULL if no token is found.

Definition at line 463 of file data_scan.c.

463 {
464 char *ptr0, *ptr1;
465
466 /* skip leading white-space and commas */
467 ptr0 = s;
468 while (skip_it(*s))
469 s++;
470 if (*s == 0)
471 return (NULL);
472 ptr1 = s;
473
474 if (*s == '"') {
475 ptr1 = s + 1;
476 /* if quoted string, skip to next quotation mark */
477 do {
478 s++;
479 } while (*s != '"' && *s);
480 if (*s == '"')
481 *s = ' ';
482 } else {
483 /* skip to first white-space following token */
484 do {
485 s++;
486 } while (*s && nskip_it(*s));
487 }
488
489 if ((s - ptr1 + 1) > lbuf) {
490 printf("buffer overflow in get_token_buf()\nstring was %s\n", ptr0);
491 exit(1);
492 }
493 strncpy(buf, ptr1, s - ptr1);
494 buf[s - ptr1] = 0;
495
496 strcpy_ss(ptr0, s);
497 return (buf);
498}

◆ tokenIsInteger()

long tokenIsInteger ( char * token)

Checks if the given token represents a valid integer.

This function verifies whether the input token string is a valid integer, which may include an optional leading '+' or '-' sign followed by digits.

Parameters
[in]tokenThe token string to check.
Returns
Returns a non-zero value if the token is a valid integer, 0 otherwise.

Definition at line 509 of file data_scan.c.

509 {
510 if (!isdigit(*token) && *token != '-' && *token != '+')
511 return 0;
512 if (!isdigit(*token) && !isdigit(*(token + 1)))
513 return 0;
514 token++;
515 while (*token)
516 if (!isdigit(*token++))
517 return 0;
518 return 1;
519}

◆ tokenIsNumber()

long tokenIsNumber ( char * token)

Checks if the given token represents a valid number.

This function verifies whether the input token string is a valid numerical value, which may include integers, floating-point numbers, and numbers in exponential notation.

Parameters
[in]tokenThe token string to check.
Returns
Returns a non-zero value if the token is a valid number, 0 otherwise.

Definition at line 530 of file data_scan.c.

530 {
531 long pointSeen, digitSeen;
532
533 if (!(digitSeen = isdigit(*token)) && *token != '-' && *token != '+' && *token != '.')
534 return 0;
535 pointSeen = *token == '.';
536 token++;
537
538 while (*token) {
539 if (isdigit(*token)) {
540 digitSeen = 1;
541 token++;
542 } else if (*token == '.') {
543 if (pointSeen)
544 return 0;
545 pointSeen = 1;
546 token++;
547 } else if (*token == 'e' || *token == 'E') {
548 if (!digitSeen)
549 return 0;
550 return tokenIsInteger(token + 1);
551 } else
552 return 0;
553 }
554 return digitSeen;
555}
long tokenIsInteger(char *token)
Checks if the given token represents a valid integer.
Definition data_scan.c:509