LAL  7.5.0.1-89842e6
StrToGPSTest.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Kipp Cannon
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 #include <errno.h>
21 #include <limits.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <lal/Date.h>
26 #include <lal/LALDebugLevel.h>
27 #include <lal/LALMalloc.h>
28 #include <lal/LALStdio.h>
29 #include <lal/XLALError.h>
30 
31 
33  const char *string;
35  const char *remainder;
37 };
38 
39 
40 static int runtest_XLALStrToGPS(const struct TESTCASE_StrToGPS *testcase)
41 {
42  int retval;
43  LIGOTimeGPS gps;
44  LIGOTimeGPS gpsCorrect;
45  char *endptr;
46  int failure = 0;
47 
48  XLALGPSSet(&gpsCorrect, testcase->sec, testcase->ns);
49 
51  retval = XLALStrToGPS(&gps, testcase->string, &endptr);
52 
53  if(retval == 0 && testcase->xlal_errno == 0) {
54  if(XLALGPSCmp(&gps, &gpsCorrect) || strcmp(endptr, testcase->remainder))
55  failure = 1;
56  } else if(XLALGetBaseErrno() != testcase->xlal_errno)
57  failure = 1;
58 
59  if(lalDebugLevel || failure)
60  fprintf(stdout, "Input = \"%s\"\n\tOutput =\t%" LAL_INT8_FORMAT " ns with \"%s\" remainder, errno %d\n\tCorrect =\t%" LAL_INT8_FORMAT " ns with \"%s\" remainder, errno %d\n\t\t===> %s\n", testcase->string, XLALGPSToINT8NS(&gps), endptr, XLALGetBaseErrno(), XLALGPSToINT8NS(&gpsCorrect), testcase->remainder, testcase->xlal_errno, failure ? "*** FAIL ***" : "Pass");
61 
62  return failure;
63 }
64 
65 
66 static int test_XLALStrToGPS(void)
67 {
68  /* Most of these test were shamelessly stolen from Peter's original
69  * code for testing LALStringToGPS() */
70  struct TESTCASE_StrToGPS general_testcases[] = {
71  {"1234.5", 1234, 500000000, "", 0},
72  {"712345678", 712345678, 0, "", 0},
73  {"00000000712346678", 712346678, 0, "", 0},
74  {"000000000000000000000000000000000712347678", 712347678, 0, "", 0},
75  {"000000000000000000712348678.00000000000000", 712348678, 0, "", 0},
76  {"000000000000000000712349678.00000000000001", 712349678, 0, "", 0},
77  {"722345678.", 722345678, 0, "", 0},
78  {"1722346678.", 1722346678, 0, "", 0},
79  {"01722347678.", 1722347678, 0, "", 0},
80  {"001722348678.", 1722348678, 0, "", 0},
81  {"732345678.0", 732345678, 0, "", 0},
82  {"742345678.7", 742345678, 700000000, "", 0},
83  {"752345678.000861", 752345678, 861000, "", 0},
84  {"762345678.000862547", 762345678, 862547, "", 0},
85  {"772345678.0008635474", 772345678, 863547, "", 0},
86  /*{"782345678.0008645475", 782345678, 864548, "", 0},*/
87  {"792345678.000865547687287", 792345678, 865548, "", 0},
88  {"702345678.9999999994", 702345678, 999999999, "", 0},
89  /*{"712345678.9999999995", 712345679, 0, "", 0},*/
90  {"722345678.9999999996", 722345679, 0, "", 0},
91  {"2000000000", 2000000000, 0, "", 0},
92  {"752345678e0", 752345678, 0, "", 0},
93  {"762345678e+0", 762345678, 0, "", 0},
94  {"772345678e-0", 772345678, 0, "", 0},
95  {"782345678e00", 782345678, 0, "", 0},
96  {"792345678e+00", 792345678, 0, "", 0},
97  {"702345678e-00", 702345678, 0, "", 0},
98  {"712345678.e0", 712345678, 0, "", 0},
99  {"722345678.e+0", 722345678, 0, "", 0},
100  {"732345678.e-0", 732345678, 0, "", 0},
101  {"742345678.00e0", 742345678, 0, "", 0},
102  {"752345678.00e+0", 752345678, 0, "", 0},
103  {"762345678.00e-0", 762345678, 0, "", 0},
104  {"772345678.06e0", 772345678, 60000000, "", 0},
105  {"782345678.06e+0", 782345678, 60000000, "", 0},
106  {"792345678.06e-0", 792345678, 60000000, "", 0},
107  {"7023.45678e5", 702345678, 0, "", 0},
108  {"7123.457785255e+05", 712345778, 525500000, "", 0},
109  {"7223458785255e-4", 722345878, 525500000, "", 0},
110  {"43d", 43, 0, "d", 0},
111  {"44.3873qr", 44, 387300000, "qr", 0},
112  {"45.3973 qr", 45, 397300000, " qr", 0},
113  {"46.3073 e2", 46, 307300000, " e2", 0},
114  {"47.3173e2", 4731, 730000000, "", 0},
115  {"6.85e7", 68500000, 0, "", 0},
116  {"6.9512345678901e7", 69512345, 678901000, "", 0},
117  {"6.05e7dkjf", 60500000, 0, "dkjf", 0},
118  {"6.15ex0", 6, 150000000, "ex0", 0},
119  {"6.25E7", 62500000, 0, "", 0},
120  {"6.35E7dkjf", 63500000, 0, "dkjf", 0},
121  {"6.45Ex0", 6, 450000000, "Ex0", 0},
122  {"752345678.5433e258", LONG_MAX, 0, "", XLAL_ERANGE},
123  {"762345678.5533e258r574", LONG_MAX, 0, "r574", XLAL_ERANGE},
124  {"772345678.5633e.258", 772345678, 563300000, "e.258", 0},
125  {"782345678.5733.258", 782345678, 573300000, ".258", 0},
126  {"792345678.5833+258", 792345678, 583300000, "+258", 0},
127  {"702345678.5933-258", 702345678, 593300000, "-258", 0},
128  {"712345678.5033.258E02", 712345678, 503300000, ".258E02", 0},
129  {"-722345678.5133", -722345679, 486700000, "", 0},
130  {"-742345678.000000625", -742345679, 999999375, "", 0},
131  {"-743345678.9999999994", -743345679, 1, "", 0},
132  /*{"-744345678.9999999995", -744345678, -999999999, "", 0},*/
133  {"-752345678.9999999996", -752345679, 0, "", 0},
134  {"5e-2", 0, 50000000, "", 0},
135  {"7e-7", 0, 700, "", 0},
136  {"6e-10", 0, 1, "", 0},
137  {"8e-11", 0, 0, "", 0},
138  {"-7e-12", 0, 0, "", 0},
139  {"-4e-6", -1, 999996000, "", 0},
140  {"-4.2e-2", -1, 958000000, "", 0},
141  {".5244", 0, 524400000, "", 0},
142  {"-.5244", -1, 475600000, "", 0},
143  {"0", 0, 0, "", 0},
144  {"+", 0, 0, "+", 0},
145  {"-", 0, 0, "-", 0},
146  {"e", 0, 0, "e", 0},
147  {"e3", 0, 0, "e3", 0},
148  {"x", 0, 0, "x", 0},
149  {"0x", 0, 0, "x", 0},
150  {"0.0000000000000000000000000000000000000001e40", 1, 0, "", 0},
151  {"10000000000000000000000000000000000000000e-40", 1, 0, "", 0},
152  {NULL, 0, 0, NULL, 0}
153  };
154  struct TESTCASE_StrToGPS overflow_testcases[] = {
155  {"7323456785", LONG_MAX, 0, "", XLAL_ERANGE},
156  {"7423456785234", LONG_MAX, 0, "", XLAL_ERANGE},
157  {"-73234567800.5233", LONG_MIN, 0, "", XLAL_ERANGE},
158  {NULL, 0, 0, NULL, 0}
159  };
160  struct TESTCASE_StrToGPS hexfloat_testcases[] = {
161  {"0x0", 0, 0, "", 0},
162  {"0x00", 0, 0, "", 0},
163  {"00x0", 0, 0, "x0", 0},
164  {"00x00", 0, 0, "x00", 0},
165  {"0x2CD7E24E.8", 752345678, 500000000, "", 0},
166  {"0x10P-6", 0, 250000000, "", 0},
167  {NULL, 0, 0, NULL, 0}
168  };
169  struct TESTCASE_StrToGPS *testcase;
170  int failures = 0;
171 
172 
173  /* run tests that all platforms must pass */
174  for(testcase = general_testcases; testcase->string; testcase++)
175  failures += runtest_XLALStrToGPS(testcase);
176 
177  /* do extra tests if ints > 32 bits overflow strtol() */
178  UINT8 rc;
179  errno = 0;
180  rc = strtol("7323456785", NULL, 0);
181  if ((rc == 0) && (errno == ERANGE))
182  for(testcase = overflow_testcases; testcase->string; testcase++)
183  failures += runtest_XLALStrToGPS(testcase);
184  else
185  fprintf(stderr, "WARNING: your C library can parse ints that LIGOTimeGPS can't store!\n");
186  errno = 0;
187 
188  /* do more tests if C library is smart enough to handle hex floats */
189  if(strtod("0x.8", NULL) == 0.5)
190  for(testcase = hexfloat_testcases; testcase->string; testcase++)
191  failures += runtest_XLALStrToGPS(testcase);
192  else
193  fprintf(stderr, "WARNING: your C library can't parse hex floats!\n");
194 
195  return failures;
196 }
197 
198 
201  const char *correct;
202 };
203 
204 
205 static int runtest_XLALGPSToStr(const struct TESTCASE_GPSToStr *testcase)
206 {
207  LIGOTimeGPS gps;
208  char *s;
209  int failure = 0;
210 
211  XLALGPSSet(&gps, testcase->sec, testcase->ns);
212 
213  XLALClearErrno();
214  s = XLALGPSToStr(NULL, &gps);
215  if(!s)
216  failure = 1;
217  else if(strcmp(s, testcase->correct))
218  failure = 1;
219 
220  if(lalDebugLevel || failure)
221  fprintf(stdout, "Input = LIGOTimeGPS(%" LAL_UINT8_FORMAT ",%" LAL_UINT8_FORMAT ")\n\tOutput =\t\"%s\"\n\tCorrect =\t\"%s\"\n\t\t===> %s\n", testcase->sec, testcase->ns, s, testcase->correct, failure ? "*** FAIL ***" : "Pass");
222  LALFree(s);
223 
224  return failure;
225 }
226 
227 
228 static int test_XLALGPSToStr(void)
229 {
230  struct TESTCASE_GPSToStr general_testcases[] = {
231  /* check determination of overall sign and the correct
232  * combining of interger and fractional parts */
233  {1, 1, "1.000000001"},
234  {1, 0, "1"},
235  {1, -1, "0.999999999"},
236  {0, 1, "0.000000001"},
237  {0, 0, "0"},
238  {0, -1, "-0.000000001"},
239  {-1, 1, "-0.999999999"},
240  {-1, 0, "-1"},
241  {-1, -1, "-1.000000001"},
242  /* check for boundary cases in handling of de-normalized
243  * numbers */
244  {0, 999999999, "0.999999999"},
245  {0, -999999999, "-0.999999999"},
246  {0, 1000000000, "1"},
247  {0, -1000000000, "-1"},
248  {0, 1000000001, "1.000000001"},
249  {0, -1000000001, "-1.000000001"},
250  {0, 2345678901, "2.345678901"},
251  {0, -2345678901, "-2.345678901"},
252  /* confirm that precision is preserved */
253  {2145678901, 0, "2145678901"},
254  {2145678901, 1, "2145678901.000000001"},
255  {2145678901, 2, "2145678901.000000002"},
256  {2145678901, 3, "2145678901.000000003"},
257  {2145678901, 4, "2145678901.000000004"},
258  {2145678901, 5, "2145678901.000000005"},
259  {-2145678901, 0, "-2145678901"},
260  {-2145678901, -1, "-2145678901.000000001"},
261  {-2145678901, -2, "-2145678901.000000002"},
262  {-2145678901, -3, "-2145678901.000000003"},
263  {-2145678901, -4, "-2145678901.000000004"},
264  {-2145678901, -5, "-2145678901.000000005"},
265  /* done */
266  {0, 0, NULL}
267  };
268  struct TESTCASE_GPSToStr *testcase;
269  int failures = 0;
270 
271 
272  for(testcase = general_testcases; testcase->correct; testcase++)
273  failures += runtest_XLALGPSToStr(testcase);
274 
275  return failures;
276 }
277 
278 
279 int main(void)
280 {
281  int failures = 0;
282 
285 
286  fprintf(stdout, "Summary of GPS string conversion tests: ");
287  if(failures) {
288  fprintf(stdout, "%d FAILURES\n", failures);
289  exit(9);
290  } else
291  fprintf(stdout, "all succeeded\n");
292  exit(0);
293 }
int XLALStrToGPS(LIGOTimeGPS *t, const char *nptr, char **endptr)
Parse an ASCII string into a LIGOTimeGPS structure.
Definition: StrToGPS.c:91
#define LALFree(p)
Definition: LALMalloc.h:96
static int test_XLALGPSToStr(void)
Definition: StrToGPSTest.c:228
static int runtest_XLALStrToGPS(const struct TESTCASE_StrToGPS *testcase)
Definition: StrToGPSTest.c:40
static int runtest_XLALGPSToStr(const struct TESTCASE_GPSToStr *testcase)
Definition: StrToGPSTest.c:205
int main(void)
Definition: StrToGPSTest.c:279
static int test_XLALStrToGPS(void)
Definition: StrToGPSTest.c:66
#define fprintf
char * XLALGPSToStr(char *, const LIGOTimeGPS *t)
Return a string containing the ASCII base 10 representation of a LIGOTimeGPS.
Definition: StrToGPS.c:274
uint64_t UINT8
Eight-byte unsigned integer; on some platforms this is equivalent to unsigned long int instead.
#define lalDebugLevel
Definition: LALDebugLevel.h:58
#define LAL_INT8_FORMAT
Definition: LALStdio.h:128
#define LAL_UINT8_FORMAT
Definition: LALStdio.h:131
int XLALGetBaseErrno(void)
Gets the XLAL base error number ignoring the internal-function-failed flag.
Definition: XLALError.c:356
int XLALClearErrno(void)
Clears the XLAL error number, returns the old value.
Definition: XLALError.c:363
@ XLAL_ERANGE
Output range error.
Definition: XLALError.h:411
int XLALGPSCmp(const LIGOTimeGPS *t0, const LIGOTimeGPS *t1)
Compares two GPS times.
Definition: XLALTime.c:174
LIGOTimeGPS * XLALGPSSet(LIGOTimeGPS *epoch, INT4 gpssec, INT8 gpsnan)
Sets GPS time given GPS integer seconds and residual nanoseconds.
Definition: XLALTime.c:63
INT8 XLALGPSToINT8NS(const LIGOTimeGPS *epoch)
Converts GPS time to nano seconds stored as an INT8.
Definition: XLALTime.c:36
Epoch relative to GPS epoch, see LIGOTimeGPS type for more details.
Definition: LALDatatypes.h:458
const char * correct
Definition: StrToGPSTest.c:201
const char * remainder
Definition: StrToGPSTest.c:35
const char * string
Definition: StrToGPSTest.c:33