00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 #include <ctype.h>
00166 #include <lal/LALStdlib.h>
00167 #include <lal/LALConstants.h>
00168 #include <lal/StringInput.h>
00169
00170 NRCSID( STRINGCONVERTC, "$Id: StringConvert.c,v 1.12 2007/06/08 14:41:53 bema Exp $" );
00171
00172
00173 #define LAL_UINT8_MAX LAL_UINT8_C(18446744073709551615)
00174 #define LAL_UINT4_MAX LAL_UINT8_C(4294967295)
00175 #define LAL_UINT2_MAX LAL_UINT8_C(65535)
00176 #define LAL_INT8_MAX LAL_UINT8_C(9223372036854775807)
00177 #define LAL_INT4_MAX LAL_UINT8_C(2147483647)
00178 #define LAL_INT2_MAX LAL_UINT8_C(32767)
00179 #define LAL_INT8_ABSMIN LAL_UINT8_C(9223372036854775808)
00180 #define LAL_INT4_ABSMIN LAL_UINT8_C(2147483648)
00181 #define LAL_INT2_ABSMIN LAL_UINT8_C(32768)
00182
00183
00184 #define LAL_UINT8_MAXDIGITS (20)
00185
00186
00187
00188 static UINT8
00189 LALStringToU8AndSign( INT2 *sign, const CHAR *string, CHAR **endptr )
00190 {
00191 union { char *s; const char *cs; } bad;
00192 const CHAR *here = string;
00193 CHAR c;
00194 UINT4 n = LAL_UINT8_MAXDIGITS - 1;
00195 UINT8 value;
00196
00197
00198 *sign = 1;
00199 while ( isspace( *here ) )
00200 here++;
00201 if ( *here == '+' )
00202 here++;
00203 else if ( *here == '-' ) {
00204 *sign = -1;
00205 here++;
00206 }
00207
00208
00209 if ( isdigit( (int)( c = *here ) ) ) {
00210 value = (UINT8)( c - '0' );
00211 here++;
00212 } else {
00213 bad.cs = string;
00214 *endptr = bad.s;
00215 return 0;
00216 }
00217
00218
00219
00220 while ( isdigit( (int)( c = *here ) ) && --n ) {
00221 value *= LAL_INT8_C(10);
00222 value += (UINT8)( c - '0' );
00223 here++;
00224 }
00225
00226
00227
00228
00229 if ( !n ) {
00230 here++;
00231 if ( isdigit( (int)( *here ) ) ) {
00232 value = LAL_UINT8_MAX;
00233 do
00234 here++;
00235 while ( isdigit( (int)( *here ) ) );
00236 } else if ( value > LAL_UINT8_MAX/LAL_INT8_C(10) ) {
00237 value = LAL_UINT8_MAX;
00238 } else {
00239 UINT8 increment = (UINT8)( c - '0' );
00240 value *= 10;
00241 if ( value > LAL_UINT8_MAX - increment )
00242 value = LAL_UINT8_MAX;
00243 else
00244 value += increment;
00245 }
00246 }
00247
00248
00249 bad.cs = here;
00250 *endptr = bad.s;
00251 return value;
00252 }
00253
00254
00255
00256 void
00257 LALStringToU2( LALStatus *stat, UINT2 *value, const CHAR *string, CHAR **endptr )
00258 {
00259 UINT8 absValue;
00260 INT2 sign;
00261 CHAR *end;
00262
00263 INITSTATUS( stat, "LALStringToU2", STRINGCONVERTC );
00264
00265
00266 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00267 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00268
00269
00270 absValue = LALStringToU8AndSign( &sign, string, &end );
00271 if ( string == end ) {
00272 if ( endptr )
00273 *endptr = end;
00274 RETURN( stat );
00275 }
00276
00277
00278 if ( absValue > LAL_UINT2_MAX )
00279 *value = (UINT2)( LAL_UINT2_MAX );
00280 else
00281 *value = (UINT2)( absValue );
00282 if ( endptr )
00283 *endptr = end;
00284 RETURN( stat );
00285 }
00286
00287
00288
00289 void
00290 LALStringToU4( LALStatus *stat, UINT4 *value, const CHAR *string, CHAR **endptr )
00291 {
00292 UINT8 absValue;
00293 INT2 sign;
00294 CHAR *end;
00295
00296 INITSTATUS( stat, "LALStringToU4", STRINGCONVERTC );
00297
00298
00299 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00300 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00301
00302
00303 absValue = LALStringToU8AndSign( &sign, string, &end );
00304 if ( string == end ) {
00305 if ( endptr )
00306 *endptr = end;
00307 RETURN( stat );
00308 }
00309
00310
00311 if ( absValue > LAL_UINT4_MAX )
00312 *value = (UINT4)( LAL_UINT4_MAX );
00313 else
00314 *value = (UINT4)( absValue );
00315 if ( endptr )
00316 *endptr = end;
00317 RETURN( stat );
00318 }
00319
00320
00321
00322 void
00323 LALStringToU8( LALStatus *stat, UINT8 *value, const CHAR *string, CHAR **endptr )
00324 {
00325 UINT8 absValue;
00326 INT2 sign;
00327 CHAR *end;
00328
00329 INITSTATUS( stat, "LALStringToU8", STRINGCONVERTC );
00330
00331
00332 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00333 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00334
00335
00336 absValue = LALStringToU8AndSign( &sign, string, &end );
00337 if ( string == end ) {
00338 if ( endptr )
00339 *endptr = end;
00340 RETURN( stat );
00341 }
00342
00343
00344 *value = absValue;
00345 if ( endptr )
00346 *endptr = end;
00347 RETURN( stat );
00348 }
00349
00350
00351
00352 void
00353 LALStringToI2( LALStatus *stat, INT2 *value, const CHAR *string, CHAR **endptr )
00354 {
00355 UINT8 absValue;
00356 INT2 sign;
00357 CHAR *end;
00358
00359 INITSTATUS( stat, "LALStringToI2", STRINGCONVERTC );
00360
00361
00362 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00363 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00364
00365
00366 absValue = LALStringToU8AndSign( &sign, string, &end );
00367 if ( string == end ) {
00368 if ( endptr )
00369 *endptr = end;
00370 RETURN( stat );
00371 }
00372
00373
00374 if ( sign > 0 ) {
00375 if ( absValue > LAL_INT2_MAX )
00376 *value = (INT2)( LAL_INT2_MAX );
00377 else
00378 *value = (INT2)( absValue );
00379 } else {
00380 if ( absValue > LAL_INT2_ABSMIN )
00381 *value = (INT2)( -LAL_INT2_ABSMIN );
00382 else
00383 *value = (INT2)( -absValue );
00384 }
00385 if ( endptr )
00386 *endptr = end;
00387 RETURN( stat );
00388 }
00389
00390
00391
00392 void
00393 LALStringToI4( LALStatus *stat, INT4 *value, const CHAR *string, CHAR **endptr )
00394 {
00395 UINT8 absValue;
00396 INT2 sign;
00397 CHAR *end;
00398
00399 INITSTATUS( stat, "LALStringToI4", STRINGCONVERTC );
00400
00401
00402 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00403 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00404
00405
00406 absValue = LALStringToU8AndSign( &sign, string, &end );
00407 if ( string == end ) {
00408 if ( endptr )
00409 *endptr = end;
00410 RETURN( stat );
00411 }
00412
00413
00414 if ( sign > 0 ) {
00415 if ( absValue > LAL_INT4_MAX )
00416 *value = (INT4)( LAL_INT4_MAX );
00417 else
00418 *value = (INT4)( absValue );
00419 } else {
00420 if ( absValue > LAL_INT4_ABSMIN )
00421 *value = (INT4)( -LAL_INT4_ABSMIN );
00422 else
00423 *value = (INT4)( -absValue );
00424 }
00425 if ( endptr )
00426 *endptr = end;
00427 RETURN( stat );
00428 }
00429
00430
00431
00432 void
00433 LALStringToI8( LALStatus *stat, INT8 *value, const CHAR *string, CHAR **endptr )
00434 {
00435 UINT8 absValue;
00436 INT2 sign;
00437 CHAR *end;
00438
00439 INITSTATUS( stat, "LALStringToI8", STRINGCONVERTC );
00440
00441
00442 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00443 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00444
00445
00446 absValue = LALStringToU8AndSign( &sign, string, &end );
00447 if ( string == end ) {
00448 if ( endptr )
00449 *endptr = end;
00450 RETURN( stat );
00451 }
00452
00453
00454 if ( sign > 0 ) {
00455 if ( absValue > LAL_INT8_MAX )
00456 *value = (INT8)( LAL_INT8_MAX );
00457 else
00458 *value = (INT8)( absValue );
00459 } else {
00460 if ( absValue > LAL_INT8_ABSMIN )
00461 *value = (INT8)( -LAL_INT8_ABSMIN );
00462 else
00463 *value = (INT8)( -absValue );
00464 }
00465 if ( endptr )
00466 *endptr = end;
00467 RETURN( stat );
00468 }
00469
00470
00471
00472 void
00473 LALStringToS( LALStatus *stat, REAL4 *value, const CHAR *string, CHAR **endptr )
00474 {
00475 REAL8 myValue;
00476 CHAR *end;
00477
00478 INITSTATUS( stat, "LALStringToS", STRINGCONVERTC );
00479
00480
00481 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00482 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00483
00484
00485 myValue = strtod( string, &end );
00486 if ( string == end ) {
00487 if ( endptr )
00488 *endptr = end;
00489 RETURN( stat );
00490 }
00491
00492
00493 if ( myValue > LAL_REAL4_MAX )
00494 *value = (REAL4)( LAL_REAL4_MAX );
00495 else if ( myValue < -LAL_REAL4_MAX )
00496 *value = (REAL4)( -LAL_REAL4_MAX );
00497 else
00498 *value = (REAL4)( myValue );
00499 if ( endptr )
00500 *endptr = end;
00501 RETURN( stat );
00502 }
00503
00504
00505
00506 void
00507 LALStringToD( LALStatus *stat, REAL8 *value, const CHAR *string, CHAR **endptr )
00508 {
00509 REAL8 myValue;
00510 CHAR *end;
00511
00512 INITSTATUS( stat, "LALStringToD", STRINGCONVERTC );
00513
00514
00515 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00516 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00517
00518
00519 myValue = strtod( string, &end );
00520 if ( string == end ) {
00521 if ( endptr )
00522 *endptr = end;
00523 RETURN( stat );
00524 }
00525
00526
00527 if ( myValue > LAL_REAL8_MAX )
00528 *value = LAL_REAL8_MAX;
00529 else if ( myValue < -LAL_REAL8_MAX )
00530 *value = -LAL_REAL8_MAX;
00531 else
00532 *value = myValue;
00533 if ( endptr )
00534 *endptr = end;
00535 RETURN( stat );
00536 }
00537
00538
00539
00540 void
00541 LALStringToC( LALStatus *stat, COMPLEX8 *value, const CHAR *string, CHAR **endptr )
00542 {
00543 REAL4 re, im;
00544 CHAR *end;
00545
00546 INITSTATUS( stat, "LALStringToC", STRINGCONVERTC );
00547 ATTATCHSTATUSPTR( stat );
00548
00549
00550 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00551 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00552
00553
00554 TRY( LALStringToS( stat->statusPtr, &re, string, &end ), stat );
00555 TRY( LALStringToS( stat->statusPtr, &im, end, &end ), stat );
00556 if ( string == end ) {
00557 if ( endptr )
00558 *endptr = end;
00559 DETATCHSTATUSPTR( stat );
00560 RETURN( stat );
00561 }
00562
00563
00564 value->re = re;
00565 value->im = im;
00566 if ( endptr )
00567 *endptr = end;
00568 DETATCHSTATUSPTR( stat );
00569 RETURN( stat );
00570 }
00571
00572
00573
00574 void
00575 LALStringToZ( LALStatus *stat, COMPLEX16 *value, const CHAR *string, CHAR **endptr )
00576 {
00577 REAL8 re, im;
00578 CHAR *end;
00579
00580 INITSTATUS( stat, "LALStringToZ", STRINGCONVERTC );
00581 ATTATCHSTATUSPTR( stat );
00582
00583
00584 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00585 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00586
00587
00588 TRY( LALStringToD( stat->statusPtr, &re, string, &end ), stat );
00589 TRY( LALStringToD( stat->statusPtr, &im, end, &end ), stat );
00590 if ( string == end ) {
00591 if ( endptr )
00592 *endptr = end;
00593 DETATCHSTATUSPTR( stat );
00594 RETURN( stat );
00595 }
00596
00597
00598 value->re = re;
00599 value->im = im;
00600 if ( endptr )
00601 *endptr = end;
00602 DETATCHSTATUSPTR( stat );
00603 RETURN( stat );
00604 }
00605
00606
00607
00608 void
00609 LALStringToGPS( LALStatus *stat, LIGOTimeGPS *value, const CHAR *string, CHAR **endptr )
00610 {
00611
00612
00613 union { char *s; const char *cs; } bad;
00614
00615 const CHAR *here = string;
00616 INT4 signval;
00617 CHAR mantissa[32];
00618 INT4 mdigits;
00619 INT4 dppos;
00620
00621
00622 const CHAR *ehere;
00623 INT4 exponent;
00624 INT2 esignval;
00625 UINT8 absValue;
00626 CHAR *eend;
00627 INT4 nanosecSet;
00628 INT4 idigit;
00629
00630 INITSTATUS( stat, "LALStringToGPS", STRINGCONVERTC );
00631 ATTATCHSTATUSPTR( stat );
00632
00633
00634 ASSERT( value, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00635 ASSERT( string, stat, STRINGINPUTH_ENUL, STRINGINPUTH_MSGENUL );
00636
00637
00638 signval = 1;
00639 while ( isspace( *here ) )
00640 here++;
00641 if ( *here == '+' )
00642 here++;
00643 else if ( *here == '-' ) {
00644 signval = -1;
00645 here++;
00646 }
00647
00648
00649
00650 mdigits = 0;
00651 dppos = -1;
00652 while ( (*here >= '0' && *here <= '9') || (*here == '.') ) {
00653
00654 if ( *here == '.' ) {
00655
00656 if ( dppos >= 0 ) {
00657
00658 break;
00659 } else {
00660
00661 dppos = mdigits;
00662 }
00663
00664 } else if ( *here == '0' && mdigits == 1 && mantissa[0] == '0' ) {
00665
00666
00667
00668 } else {
00669
00670
00671 if ( (UINT4) mdigits < sizeof(mantissa) ) {
00672 mantissa[mdigits] = *here;
00673 mdigits++;
00674 }
00675 }
00676
00677 here++;
00678
00679 }
00680
00681
00682
00683 if ( mdigits == 0 ) {
00684 if ( endptr ) {
00685 bad.cs = string;
00686 *endptr = bad.s;
00687 }
00688 DETATCHSTATUSPTR( stat );
00689 RETURN( stat );
00690 }
00691
00692
00693
00694 if ( dppos == -1 ) { dppos = mdigits; }
00695
00696
00697 exponent = 0;
00698 if ( *here == 'E' || *here == 'e' ) {
00699
00700 ehere = here + 1;
00701
00702
00703 absValue = LALStringToU8AndSign( &esignval, ehere, &eend );
00704 if ( eend == ehere ) {
00705
00706
00707
00708 } else {
00709
00710 exponent = (INT4) ( esignval * absValue );
00711
00712 here = eend;
00713 }
00714
00715 }
00716
00717
00718 dppos += exponent;
00719
00720
00721
00722
00723
00724 nanosecSet = 0;
00725
00726 if ( dppos > 11 ) {
00727
00728 if ( signval == 1 ) {
00729 value->gpsSeconds = (INT4) LAL_INT4_MAX;
00730 value->gpsNanoSeconds = 999999999;
00731 } else {
00732 value->gpsSeconds = (INT4)( -LAL_INT4_ABSMIN );
00733 value->gpsNanoSeconds = 0;
00734 }
00735
00736 } else if ( dppos < -9 ) {
00737
00738 value->gpsSeconds = 0;
00739 value->gpsNanoSeconds = 0;
00740
00741 } else {
00742
00743
00744 absValue = 0;
00745 for ( idigit=0; idigit<dppos && idigit<mdigits; idigit++ ) {
00746 absValue = 10*absValue + (UINT8) ( mantissa[idigit]-'0' );
00747 }
00748
00749 for ( ; idigit<dppos; idigit++ ) {
00750 absValue *= 10;
00751 }
00752
00753
00754 if ( signval > 0 ) {
00755 if ( absValue > LAL_INT4_MAX ) {
00756 value->gpsSeconds = (INT4)( LAL_INT4_MAX );
00757 value->gpsNanoSeconds = 999999999;
00758 nanosecSet = 1;
00759 } else
00760 value->gpsSeconds = (INT4)( absValue );
00761 } else {
00762 if ( absValue >= LAL_INT4_ABSMIN ) {
00763 value->gpsSeconds = (INT4)( -LAL_INT4_ABSMIN );
00764 value->gpsNanoSeconds = 0;
00765 nanosecSet = 1;
00766 } else
00767 value->gpsSeconds = (INT4)( -absValue );
00768 }
00769
00770
00771 if ( ! nanosecSet ) {
00772
00773 absValue = 0;
00774 for ( idigit=dppos; idigit<dppos+9 && idigit<mdigits; idigit++ ) {
00775 if ( idigit >= 0 ) {
00776 absValue = 10*absValue + (UINT8) ( mantissa[idigit]-'0' );
00777 }
00778 }
00779
00780 if ( idigit==dppos+9 && idigit<mdigits ) {
00781 if ( mantissa[idigit] >= '5' ) {
00782 absValue++;
00783 }
00784 }
00785
00786 for ( ; idigit<dppos+9; idigit++ ) {
00787 absValue *= 10;
00788 }
00789
00790 value->gpsNanoSeconds = (INT4) ( signval * absValue );
00791
00792
00793 if ( value->gpsNanoSeconds >= 1000000000 ) {
00794 value->gpsNanoSeconds -= 1000000000;
00795 value->gpsSeconds += 1;
00796 }
00797
00798 while ( value->gpsNanoSeconds < 0 ) {
00799 value->gpsNanoSeconds += 1000000000;
00800 value->gpsSeconds -= 1;
00801 }
00802
00803 }
00804
00805 }
00806
00807
00808 if ( endptr ) {
00809 bad.cs = here;
00810 *endptr = bad.s;
00811 }
00812 DETATCHSTATUSPTR( stat );
00813 RETURN( stat );
00814 }