File Coverage

palsrc/palDafin.c
Criterion Covered Total %
statement 23 25 92.0
branch 15 36 41.6
condition n/a
subroutine n/a
pod n/a
total 38 61 62.3


line stmt bran cond sub pod time code
1             /*
2             *+
3             * Name:
4             * palDafin
5              
6             * Purpose:
7             * Sexagesimal character string to angle
8              
9             * Language:
10             * Starlink ANSI C
11              
12             * Type of Module:
13             * Library routine
14              
15             * Invocation:
16             * void palDafin ( const char *string, int *ipos, double *a, int *j );
17              
18             * Arguments:
19             * string = const char * (Given)
20             * String containing deg, arcmin, arcsec fields
21             * ipos = int * (Given & Returned)
22             * Position to start decoding "string". First character
23             * is position 1 for compatibility with SLA. After
24             * calling this routine "iptr" will be positioned after
25             * the sexagesimal string.
26             * a = double * (Returned)
27             * Angle in radians.
28             * j = int * (Returned)
29             * status: 0 = OK
30             * +1 = default, A unchanged
31             * -1 = bad degrees )
32             * -2 = bad arcminutes ) (note 3)
33             * -3 = bad arcseconds )
34              
35             * Description:
36             * Extracts an angle from a sexagesimal string with degrees, arcmin,
37             * arcsec fields using space or comma delimiters.
38              
39             * Authors:
40             * TIMJ: Tim Jenness (JAC, Hawaii)
41             * PTW: Patrick T. Wallace
42             * {enter_new_authors_here}
43              
44             * Example:
45             * argument before after
46             *
47             * STRING '-57 17 44.806 12 34 56.7' unchanged
48             * IPTR 1 16 (points to 12...)
49             * A ? -1.00000D0
50             * J ? 0
51              
52             * Notes:
53             * - The first three "fields" in STRING are degrees, arcminutes,
54             * arcseconds, separated by spaces or commas. The degrees field
55             * may be signed, but not the others. The decoding is carried
56             * out by the palDfltin routine and is free-format.
57             * - Successive fields may be absent, defaulting to zero. For
58             * zero status, the only combinations allowed are degrees alone,
59             * degrees and arcminutes, and all three fields present. If all
60             * three fields are omitted, a status of +1 is returned and A is
61             * unchanged. In all other cases A is changed.
62             * - Range checking:
63             *
64             * The degrees field is not range checked. However, it is
65             * expected to be integral unless the other two fields are absent.
66             *
67             * The arcminutes field is expected to be 0-59, and integral if
68             * the arcseconds field is present. If the arcseconds field
69             * is absent, the arcminutes is expected to be 0-59.9999...
70             *
71             * The arcseconds field is expected to be 0-59.9999...
72             *
73             * - Decoding continues even when a check has failed. Under these
74             * circumstances the field takes the supplied value, defaulting
75             * to zero, and the result A is computed and returned.
76             * - Further fields after the three expected ones are not treated
77             * as an error. The pointer IPOS is left in the correct state
78             * for further decoding with the present routine or with palDfltin
79             * etc. See the example, above.
80             * - If STRING contains hours, minutes, seconds instead of degrees
81             * etc, or if the required units are turns (or days) instead of
82             * radians, the result A should be multiplied as follows:
83             *
84             * for to obtain multiply
85             * STRING A in A by
86             *
87             * d ' " radians 1 = 1.0
88             * d ' " turns 1/2pi = 0.1591549430918953358
89             * h m s radians 15 = 15.0
90             * h m s days 15/2pi = 2.3873241463784300365
91              
92             * History:
93             * 2012-03-08 (TIMJ):
94             * Initial version from SLA/F using Fortran documentation
95             * Adapted with permission from the Fortran SLALIB library.
96             * 2012-10-17 (TIMJ):
97             * Fix range check on arcminute value.
98             * {enter_further_changes_here}
99              
100             * Copyright:
101             * Copyright (C) 1996 Rutherford Appleton Laboratory
102             * Copyright (C) 2012 Science and Technology Facilities Council.
103             * All Rights Reserved.
104              
105             * Licence:
106             * This program is free software; you can redistribute it and/or
107             * modify it under the terms of the GNU General Public License as
108             * published by the Free Software Foundation; either version 3 of
109             * the License, or (at your option) any later version.
110             *
111             * This program is distributed in the hope that it will be
112             * useful, but WITHOUT ANY WARRANTY; without even the implied
113             * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
114             * PURPOSE. See the GNU General Public License for more details.
115             *
116             * You should have received a copy of the GNU General Public License
117             * along with this program; if not, write to the Free Software
118             * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
119             * MA 02110-1301, USA.
120              
121             * Bugs:
122             * {note_any_bugs_here}
123             *-
124             */
125              
126             #include "pal.h"
127             #include "palmac.h"
128             #include "pal1sofa.h"
129              
130             #include
131              
132 3           void palDafin ( const char *string, int *ipos, double *a, int *j ) {
133              
134 3           int jd = 0; /* Status for degree parsing */
135 3           int jm = 0; /* Status for arcmin parsing */
136 3           int js = 0; /* Status for arcsec parsing */
137             int jf = 0; /* Internal copy of status */
138 3           double deg = 0.0;
139 3           double arcmin = 0.0;
140 3           double arcsec = 0.0;
141              
142             /* Decode degrees, arcminutes, arcseconds */
143 3           palDfltin( string, ipos, °, &jd );
144 3 50         if (jd > 1) {
145             jf = -1;
146             } else {
147              
148 3           palDfltin( string, ipos, &arcmin, &jm );
149 3 50         if ( jm < 0 || jm > 1 ) {
150             jf = -2;
151             } else {
152              
153 3           palDfltin( string, ipos, &arcsec, &js );
154 3 50         if (js < 0 || js > 1) {
155             jf = -3;
156              
157 3 50         } else if (jd > 0) { /* See if combination of fields is credible */
158             /* No degrees: arcmin, arcsec ought also to be absent */
159 0 0         if (jm == 0) {
160             /* Suspect arcmin */
161             jf = -2;
162 0 0         } else if (js == 0) {
163             /* Suspect arcsec */
164             jf = -3;
165             } else {
166             /* All three fields absent */
167             jf = 1;
168             }
169              
170 3 50         } else if (jm != 0 && js == 0) { /* Deg present: if arcsec present should have arcmin */
    0          
171             jf = -3;
172              
173             /* Tests for range and integrality */
174 3 50         } else if (jm == 0 && DINT(deg) != deg) { /* Degrees */
    100          
    50          
175             jf = -1;
176              
177 3 50         } else if ( (js == 0 && DINT(arcmin) != arcmin) || arcmin >= 60.0 ) { /* Arcmin */
    0          
    0          
    50          
178             jf = -2;
179              
180 3 50         } else if (arcsec >= 60.0) { /* Arcsec */
181             jf = -3;
182             }
183             }
184             }
185              
186             /* Unless all three fields absent, compute angle value */
187 3 50         if (jf <= 0) {
188 3           *a = PAL__DAS2R * ( 60.0 * ( 60.0 * fabs(deg) + arcmin) + arcsec );
189 3 100         if ( jd < 0 ) *a *= -1.;
190             }
191              
192 3           *j = jf;
193              
194 3           }