source: trunk/FACT++/pal/palIntin.c@ 19907

Last change on this file since 19907 was 18347, checked in by tbretz, 9 years ago
File size: 5.2 KB
Line 
1/*
2*+
3* Name:
4* palIntin
5
6* Purpose:
7* Convert free-format input into an integer
8
9* Language:
10* Starlink ANSI C
11
12* Type of Module:
13* Library routine
14
15* Invocation:
16* void palIntin( const char * string, int *nstrt,
17* long *ireslt, int *jflag );
18
19* Arguments:
20* string = const char * (Given)
21* String containing number to be decoded.
22* nstrt = int * (Given and Returned)
23* Character number indicating where decoding should start.
24* On output its value is updated to be the location of the
25* possible next value. For compatibility with SLA the first
26* character is index 1.
27* ireslt = long * (Returned)
28* Result. Not updated when jflag=1.
29* jflag = int * (Returned)
30* status: -1 = -OK, 0 = +OK, 1 = null, 2 = error
31
32* Description:
33* Extracts a number from an input string starting at the specified
34* index.
35
36* Authors:
37* TIMJ: Tim Jenness (JAC, Hawaii)
38* {enter_new_authors_here}
39
40* Notes:
41* - Uses the strtol() system call to do the parsing. This may lead to
42* subtle differences when compared to the SLA/F parsing.
43* - Commas are recognized as a special case and are skipped if one happens
44* to be the next character when updating nstrt. Additionally the output
45* nstrt position will skip past any trailing space.
46* - If no number can be found flag will be set to 1.
47* - If the number overflows or underflows jflag will be set to 2. For overflow
48* the returned result will have the value LONG_MAX, for underflow it
49* will have the value LONG_MIN.
50
51* History:
52* 2012-03-15 (TIMJ):
53* Initial version
54* Matches the SLALIB interface but brand new implementation using
55* C library calls and not a direct port of the Fortran.
56* 2014-08-07 (TIMJ):
57* Check for isblank availability.
58* {enter_further_changes_here}
59
60* Copyright:
61* Copyright (C) 2012,2014 Science and Technology Facilities Council.
62* All Rights Reserved.
63
64* Licence:
65* This program is free software; you can redistribute it and/or
66* modify it under the terms of the GNU General Public License as
67* published by the Free Software Foundation; either version 3 of
68* the License, or (at your option) any later version.
69*
70* This program is distributed in the hope that it will be
71* useful, but WITHOUT ANY WARRANTY; without even the implied
72* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
73* PURPOSE. See the GNU General Public License for more details.
74*
75* You should have received a copy of the GNU General Public License
76* along with this program; if not, write to the Free Software
77* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
78* MA 02110-1301, USA.
79
80* Bugs:
81* {note_any_bugs_here}
82*-
83*/
84
85#if HAVE_CONFIG_H
86# include <config.h>
87#endif
88
89#include <stdlib.h>
90#include <errno.h>
91
92/* isblank() is a C99 feature so we just reimplement it if it is missing */
93#if HAVE_ISBLANK
94#ifndef _ISOC99_SOURCE
95#define _ISOC99_SOURCE
96#endif
97#include <ctype.h>
98# define ISBLANK isblank
99#else
100
101static int ISBLANK( int c ) {
102 return ( c == ' ' || c == '\t' );
103}
104
105#endif
106
107/* Still need ctype for isalpha and isdigit */
108#include <ctype.h>
109
110#include "pal.h"
111
112void palIntin( const char * string, int *nstrt,
113 long *ireslt, int *jflag ) {
114
115 const char *strstart = NULL; /* Pointer to start of search */
116 const char * ctemp = NULL; /* Pointer into string */
117 char * endptr = NULL;/* Pointer to string after number */
118 int retval; /* Return value from strtol */
119 int hasminus; /* is this a -0 */
120
121 /* strtol man page indicates that we should reset errno before
122 calling strtod */
123 errno = 0;
124
125 /* Locate the start postion */
126 strstart = &(string[*nstrt-1]);
127
128 /* We have to be able to deal with -0 so we have to search the
129 string first and look for the negative */
130 hasminus = 0;
131 ctemp = strstart;
132 while ( ctemp != '\0' ) {
133 if (isdigit(*ctemp)) break;
134 /* Reset so that - 12345 is not a negative number */
135 hasminus = 0;
136 /* Flag that we have found a minus */
137 if (*ctemp == '-') hasminus = 1;
138 ctemp++;
139 }
140
141 /* Look for the number using the system call, offsetting using
142 1-based counter. */
143 retval = strtol( strstart, &endptr, 10 );
144 if (retval == 0.0 && endptr == strstart) {
145 /* conversion did not find anything */
146 *jflag = 1;
147
148 /* but SLA compatibility requires that we step
149 through to remove leading spaces. We also step
150 through alphabetic characters since they can never
151 be numbers. Skip past a "+" since it doesn't gain
152 us anything and matches slalib. */
153 while (ISBLANK(*endptr) || isalpha(*endptr) || *endptr == '+' ) {
154 endptr++;
155 }
156
157 } else if ( errno == ERANGE ) {
158 *jflag = 2;
159 } else {
160 if ( retval < 0 || hasminus ) {
161 *jflag = -1;
162 } else {
163 *jflag = 0;
164 }
165 }
166
167 /* Sort out the position for the next index */
168 *nstrt = endptr - string + 1;
169
170 /* Skip a comma */
171 if (*endptr == ',') {
172 (*nstrt)++;
173 } else {
174 /* jump past any leading spaces for the next part of the string */
175 ctemp = endptr;
176 while ( ISBLANK(*ctemp) ) {
177 (*nstrt)++;
178 ctemp++;
179 }
180 }
181
182 /* And the result unless we found nothing */
183 if (*jflag != 1) *ireslt = retval;
184
185}
Note: See TracBrowser for help on using the repository browser.