1 /* 2 3 -Disclaimer 4 5 THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE 6 CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. 7 GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE 8 ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE 9 PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" 10 TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY 11 WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A 12 PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC 13 SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE 14 SOFTWARE AND RELATED MATERIALS, HOWEVER USED. 15 16 IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA 17 BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT 18 LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, 20 REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE 21 REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. 22 23 RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF 24 THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY 25 CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE 26 ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. 27 28 */ 29 30 /* 31 CSPICE private macro file. 32 33 -Particulars 34 35 Current list of macros (spelling counts) 36 37 BLANK 38 C2F_MAP_CELL 39 C2F_MAP_CELL2 40 C2F_MAP_CELL3 41 CELLINIT 42 CELLINIT2 43 CELLINIT3 44 CELLISSETCHK 45 CELLISSETCHK2 46 CELLISSETCHK2_VAL 47 CELLISSETCHK3 48 CELLISSETCHK3_VAL 49 CELLISSETCHK_VAL 50 CELLMATCH2 51 CELLMATCH2_VAL 52 CELLMATCH3 53 CELLMATCH3_VAL 54 CELLTYPECHK 55 CELLTYPECHK2 56 CELLTYPECHK2_VAL 57 CELLTYPECHK3 58 CELLTYPECHK3_VAL 59 CELLTYPECHK_VAL 60 CHKFSTR 61 CHKFSTR_VAL 62 CHKOSTR 63 CHKOSTR_VAL 64 CHKPTR 65 Constants 66 Even 67 F2C_MAP_CELL 68 Index values 69 MOVED 70 MOVEI 71 MaxAbs 72 MaxVal 73 MinAbs 74 MinVal 75 Odd 76 SpiceError 77 TolOrFail 78 79 -Restrictions 80 81 This is a private macro file for use within CSPICE. 82 Do not use or alter any entry. Or else! 83 84 -Author_and_Institution 85 86 N.J. Bachman (JPL) 87 E.D. Wright (JPL) 88 89 -Version 90 91 -CSPICE Version 5.0.0, 07-FEB-2017 (NJB) 92 93 Updated MaxAbs and MinAbs macros to cast their input arguments 94 to type double. 95 96 -CSPICE Version 4.3.0, 18-SEP-2013 (NJB) 97 98 Bug fix: missing comma was added to argument list 99 in body of macro CELLTYPECHK3_VAL. 100 101 -CSPICE Version 4.2.0, 16-FEB-2005 (NJB) 102 103 Bug fix: in the macro C2F_MAP_CELL, error checking has been 104 added after the sequence of calls to ssizec_ and scardc_. 105 If either of these routines signals an error, the dynamically 106 allocated memory for the "Fortran cell" is freed. 107 108 -CSPICE Version 4.1.0, 06-DEC-2002 (NJB) 109 110 Bug fix: added previous missing, bracketing parentheses to 111 references to input cell pointer argument in macro 112 CELLINIT. 113 114 Changed CELLINIT macro so it no longer initializes to zero 115 length all strings in data array of a character cell. Instead, 116 strings are terminated with a null in their final element. 117 118 -CSPICE Version 4.0.0, 22-AUG-2002 (NJB) 119 120 Added macro definitions to support CSPICE cells and sets: 121 122 C2F_MAP_CELL 123 C2F_MAP_CELL2 124 C2F_MAP_CELL3 125 CELLINIT 126 CELLINIT2 127 CELLINIT3 128 CELLISSETCHK 129 CELLISSETCHK2 130 CELLISSETCHK2_VAL 131 CELLISSETCHK3 132 CELLISSETCHK3_VAL 133 CELLISSETCHK_VAL 134 CELLMATCH2 135 CELLMATCH2_VAL 136 CELLMATCH3 137 CELLMATCH3_VAL 138 CELLTYPECHK 139 CELLTYPECHK2 140 CELLTYPECHK2_VAL 141 CELLTYPECHK3 142 CELLTYPECHK3_VAL 143 CELLTYPECHK_VAL 144 F2C_MAP_CELL 145 146 -CSPICE Version 3.0.0, 09-JAN-1998 (NJB) 147 148 Added output string check macros CHKOSTR and CHKOSTR_VAL. 149 Removed variable name arguments from macros 150 151 CHKPTR 152 CHKPTR_VAL 153 CHKFSTR 154 CHKRSTR_VAL 155 156 The strings containing names of the checked variables are now 157 generated from the variables themselves via the # operator. 158 159 -CSPICE Version 2.0.0, 03-DEC-1997 (NJB) 160 161 Added pointer check macro CHKPTR and Fortran string check macro 162 CHKFSTR. 163 164 -CSPICE Version 1.0.0, 25-OCT-1997 (EDW) 165 */ 166 167 168 169 #include <math.h> 170 #include <string.h> 171 #include "SpiceZdf.h" 172 173 174 #define MOVED( arrfrm, ndim, arrto ) \ 175 \ 176 ( memmove ( (void*) (arrto) , \ 177 (void*) (arrfrm), \ 178 sizeof (SpiceDouble) * (ndim) ) ) 179 180 181 182 183 184 #define MOVEI( arrfrm, ndim, arrto ) \ 185 \ 186 ( memmove ( (void*) (arrto) , \ 187 (void*) (arrfrm), \ 188 sizeof (SpiceInt) * (ndim) ) ) 189 190 191 192 193 194 /* 195 Define a tolerance test for those pesky double precision reals. 196 True if the difference is less than the tolerance, false otherwise. 197 The tolerance refers to a percentage. x, y and tol should be declared 198 double. All values are assumed to be non-zero. Okay? 199 */ 200 201 #define TolOrFail( x, y, tol ) \ 202 \ 203 ( fabs( x-y ) < ( tol * fabs(x) ) ) 204 205 206 207 208 209 /* 210 Simple error output through standard SPICE error system . Set the error 211 message and the type 212 */ 213 214 #define SpiceError( errmsg, errtype ) \ 215 \ 216 { \ 217 setmsg_c ( errmsg ); \ 218 sigerr_c ( errtype ); \ 219 } 220 221 222 223 224 225 226 /* 227 Return a value which is the maximum/minimum of the absolute values of 228 two values. 229 */ 230 231 #define MaxAbs(a,b) \ 232 \ 233 ( fabs((double)(a)) >= fabs((double)(b)) ? \ 234 fabs((double)(a)) : fabs((double)(b)) ) 235 236 #define MinAbs(a,b) \ 237 \ 238 ( fabs((double)(a)) < fabs((double)(b)) ? \ 239 fabs((double)(a)) : fabs((double)(b)) ) 240 241 242 /* 243 Return a value which is the maximum/minimum value of two values. 244 */ 245 246 #define MaxVal(A,B) ( (A) >= (B) ? (A) : (B) ) 247 #define MinVal(A,B) ( (A) < (B) ? (A) : (B) ) 248 249 250 251 252 253 /* 254 Determine whether a value is even or odd 255 */ 256 #define Even( x ) ( ( (x) & 1 ) == 0 ) 257 #define Odd ( x ) ( ( (x) & 1 ) != 0 ) 258 259 260 261 262 263 /* 264 Array indexes for vectors. 265 */ 266 267 #define SpiceX 0 268 #define SpiceY 1 269 #define SpiceZ 2 270 #define SpiceVx 3 271 #define SpiceVy 4 272 #define SpiceVz 5 273 274 275 276 277 /* 278 Physical constants and dates. 279 */ 280 281 #define B1900 2415020.31352 282 #define J1900 2415020.0 283 #define JYEAR 31557600.0 284 #define TYEAR 31556925.9747 285 #define J1950 2433282.5 286 #define SPD 86400.0 287 #define B1950 2433282.42345905 288 #define J2100 2488070.0 289 #define CLIGHT 299792.458 290 #define J2000 2451545.0 291 292 293 294 295 296 /* 297 Common literal values. 298 */ 299 300 #define NULLCHAR ( (SpiceChar ) 0 ) 301 #define NULLCPTR ( (SpiceChar * ) 0 ) 302 #define BLANK ( (SpiceChar ) ' ' ) 303 304 305 306 /* 307 Macro CHKPTR is used for checking for a null pointer. CHKPTR uses 308 the constants 309 310 CHK_STANDARD 311 CHK_DISCOVER 312 CHK_REMAIN 313 314 to control tracing behavior. Values and meanings are: 315 316 CHK_STANDARD Standard tracing. If an error 317 is found, signal it, check out 318 and return. 319 320 CHK_DISCOVER Discovery check-in. If an 321 error is found, check in, signal 322 the error, check out, and return. 323 324 CHK_REMAIN If an error is found, signal it. 325 Do not check out or return. This 326 would allow the caller to clean up 327 before returning, if necessary. 328 In such cases the caller must test 329 failed_c() after the macro call. 330 331 CHKPTR should be used in void functions. In non-void functions, 332 use CHKPTR_VAL, which is defined below. 333 334 */ 335 336 #define CHK_STANDARD 1 337 #define CHK_DISCOVER 2 338 #define CHK_REMAIN 3 339 340 #define CHKPTR( errHandling, modname, pointer ) \ 341 \ 342 if ( (void *)(pointer) == (void *)0 ) \ 343 { \ 344 if ( (errHandling) == CHK_DISCOVER ) \ 345 { \ 346 chkin_c ( modname ); \ 347 } \ 348 \ 349 setmsg_c ( "Pointer \"#\" is null; a non-null " \ 350 "pointer is required." ); \ 351 errch_c ( "#", (#pointer) ); \ 352 sigerr_c ( "SPICE(NULLPOINTER)" ); \ 353 \ 354 if ( ( (errHandling) == CHK_DISCOVER ) \ 355 || ( (errHandling) == CHK_STANDARD ) ) \ 356 { \ 357 chkout_c ( modname ); \ 358 return; \ 359 } \ 360 } 361 362 363 #define CHKPTR_VAL( errHandling, modname, pointer, retval ) \ 364 \ 365 if ( (void *)(pointer) == (void *)0 ) \ 366 { \ 367 if ( (errHandling) == CHK_DISCOVER ) \ 368 { \ 369 chkin_c ( modname ); \ 370 } \ 371 \ 372 setmsg_c ( "Pointer \"#\" is null; a non-null " \ 373 "pointer is required." ); \ 374 errch_c ( "#", (#pointer) ); \ 375 sigerr_c ( "SPICE(NULLPOINTER)" ); \ 376 \ 377 if ( ( (errHandling) == CHK_DISCOVER ) \ 378 || ( (errHandling) == CHK_STANDARD ) ) \ 379 { \ 380 chkout_c ( modname ); \ 381 return ( retval ); \ 382 } \ 383 } 384 385 386 /* 387 Macro CHKFSTR checks strings that are to be passed to Fortran or 388 f2c'd Fortran routines. Such strings must have non-zero length, 389 and their pointers must be non-null. 390 391 CHKFSTR should be used in void functions. In non-void functions, 392 use CHKFSTR_VAL, which is defined below. 393 */ 394 395 #define CHKFSTR( errHandling, modname, string ) \ 396 \ 397 CHKPTR ( errHandling, modname, string ); \ 398 \ 399 if ( ( (void *)string != (void *)0 ) \ 400 && ( strlen(string) == 0 ) ) \ 401 { \ 402 if ( (errHandling) == CHK_DISCOVER ) \ 403 { \ 404 chkin_c ( modname ); \ 405 } \ 406 \ 407 setmsg_c ( "String \"#\" has length zero." ); \ 408 errch_c ( "#", (#string) ); \ 409 sigerr_c ( "SPICE(EMPTYSTRING)" ); \ 410 \ 411 if ( ( (errHandling) == CHK_DISCOVER ) \ 412 || ( (errHandling) == CHK_STANDARD ) ) \ 413 { \ 414 chkout_c ( modname ); \ 415 return; \ 416 } \ 417 } 418 419 #define CHKFSTR_VAL( errHandling, modname, string, retval ) \ 420 \ 421 CHKPTR_VAL( errHandling, modname, string, retval); \ 422 \ 423 if ( ( (void *)string != (void *)0 ) \ 424 && ( strlen(string) == 0 ) ) \ 425 { \ 426 if ( (errHandling) == CHK_DISCOVER ) \ 427 { \ 428 chkin_c ( modname ); \ 429 } \ 430 \ 431 setmsg_c ( "String \"#\" has length zero." ); \ 432 errch_c ( "#", (#string) ); \ 433 sigerr_c ( "SPICE(EMPTYSTRING)" ); \ 434 \ 435 if ( ( (errHandling) == CHK_DISCOVER ) \ 436 || ( (errHandling) == CHK_STANDARD ) ) \ 437 { \ 438 chkout_c ( modname ); \ 439 return ( retval ); \ 440 } \ 441 } 442 443 444 /* 445 Macro CHKOSTR checks output string pointers and the associated 446 string length values supplied as input arguments. Output string 447 pointers must be non-null, and the string lengths must be at 448 least 2, so Fortran routine can write at least one character to 449 the output string, and so a null terminator can be appended. 450 CHKOSTR should be used in void functions. In non-void functions, 451 use CHKOSTR_VAL, which is defined below. 452 */ 453 454 #define CHKOSTR( errHandling, modname, string, length ) \ 455 \ 456 CHKPTR ( errHandling, modname, string ); \ 457 \ 458 if ( ( (void *)string != (void *)0 ) \ 459 && ( length < 2 ) ) \ 460 { \ 461 if ( (errHandling) == CHK_DISCOVER ) \ 462 { \ 463 chkin_c ( modname ); \ 464 } \ 465 \ 466 setmsg_c ( "String \"#\" has length #; must be >= 2." ); \ 467 errch_c ( "#", (#string) ); \ 468 errint_c ( "#", (length) ); \ 469 sigerr_c ( "SPICE(STRINGTOOSHORT)" ); \ 470 \ 471 if ( ( (errHandling) == CHK_DISCOVER ) \ 472 || ( (errHandling) == CHK_STANDARD ) ) \ 473 { \ 474 chkout_c ( modname ); \ 475 return; \ 476 } \ 477 } 478 479 480 #define CHKOSTR_VAL( errHandling, modname, string, length, retval ) \ 481 \ 482 CHKPTR_VAL( errHandling, modname, string, retval ); \ 483 \ 484 if ( ( (void *)string != (void *)0 ) \ 485 && ( length < 2 ) ) \ 486 { \ 487 if ( (errHandling) == CHK_DISCOVER ) \ 488 { \ 489 chkin_c ( modname ); \ 490 } \ 491 \ 492 setmsg_c ( "String \"#\" has length #; must be >= 2." ); \ 493 errch_c ( "#", (#string) ); \ 494 errint_c ( "#", (length) ); \ 495 sigerr_c ( "SPICE(STRINGTOOSHORT)" ); \ 496 \ 497 if ( ( (errHandling) == CHK_DISCOVER ) \ 498 || ( (errHandling) == CHK_STANDARD ) ) \ 499 { \ 500 chkout_c ( modname ); \ 501 return ( retval ); \ 502 } \ 503 } 504 505 506 /* 507 Definitions for Cells and Sets 508 */ 509 510 511 /* 512 Cell initialization macros 513 */ 514 #define CELLINIT( cellPtr ) \ 515 \ 516 if ( !( (cellPtr)->init ) ) \ 517 { \ 518 if ( (cellPtr)->dtype == SPICE_CHR ) \ 519 { \ 520 /* \ 521 Make sure all elements of the data array, including \ 522 the control area, start off null-terminated. We place \ 523 the null character in the final element of each string, \ 524 so as to avoid wiping out data that may have been \ 525 assigned to the data array prior to initialization. \ 526 */ \ 527 SpiceChar * sPtr; \ 528 SpiceInt i; \ 529 SpiceInt nmax; \ 530 \ 531 nmax = SPICE_CELL_CTRLSZ + (cellPtr)->size; \ 532 \ 533 for ( i = 1; i <= nmax; i++ ) \ 534 { \ 535 sPtr = (SpiceChar *)((cellPtr)->base) \ 536 + i * (cellPtr)->length \ 537 - 1; \ 538 \ 539 *sPtr = NULLCHAR; \ 540 } \ 541 } \ 542 else \ 543 { \ 544 zzsynccl_c ( C2F, (cellPtr) ); \ 545 } \ 546 \ 547 (cellPtr)->init = SPICETRUE; \ 548 } 549 550 551 #define CELLINIT2( cellPtr1, cellPtr2 ) \ 552 \ 553 CELLINIT ( cellPtr1 ); \ 554 CELLINIT ( cellPtr2 ); 555 556 557 #define CELLINIT3( cellPtr1, cellPtr2, cellPtr3 ) \ 558 \ 559 CELLINIT ( cellPtr1 ); \ 560 CELLINIT ( cellPtr2 ); \ 561 CELLINIT ( cellPtr3 ); 562 563 564 /* 565 Data type checking macros: 566 */ 567 #define CELLTYPECHK( errHandling, modname, dType, cellPtr1 ) \ 568 \ 569 if ( (cellPtr1)->dtype != (dType) ) \ 570 { \ 571 SpiceChar * typstr[3] = \ 572 { \ 573 "character", "double precision", "integer" \ 574 }; \ 575 \ 576 if ( (errHandling) == CHK_DISCOVER ) \ 577 { \ 578 chkin_c ( modname ); \ 579 } \ 580 \ 581 setmsg_c ( "Data type of # is #; expected type " \ 582 "is #." ); \ 583 errch_c ( "#", (#cellPtr1) ); \ 584 errch_c ( "#", typstr[ (cellPtr1)->dtype ] ); \ 585 errch_c ( "#", typstr[ dType ] ); \ 586 sigerr_c ( "SPICE(TYPEMISMATCH)" ); \ 587 \ 588 if ( ( (errHandling) == CHK_DISCOVER ) \ 589 || ( (errHandling) == CHK_STANDARD ) ) \ 590 { \ 591 chkout_c ( modname ); \ 592 return; \ 593 } \ 594 } 595 596 597 #define CELLTYPECHK_VAL( errHandling, modname, \ 598 dType, cellPtr1, retval ) \ 599 \ 600 if ( (cellPtr1)->dtype != (dType) ) \ 601 { \ 602 SpiceChar * typstr[3] = \ 603 { \ 604 "character", "double precision", "integer" \ 605 }; \ 606 \ 607 if ( (errHandling) == CHK_DISCOVER ) \ 608 { \ 609 chkin_c ( modname ); \ 610 } \ 611 \ 612 setmsg_c ( "Data type of # is #; expected type " \ 613 "is #." ); \ 614 errch_c ( "#", (#cellPtr1) ); \ 615 errch_c ( "#", typstr[ (cellPtr1)->dtype ] ); \ 616 errch_c ( "#", typstr[ dType ] ); \ 617 sigerr_c ( "SPICE(TYPEMISMATCH)" ); \ 618 \ 619 if ( ( (errHandling) == CHK_DISCOVER ) \ 620 || ( (errHandling) == CHK_STANDARD ) ) \ 621 { \ 622 chkout_c ( modname ); \ 623 return (retval); \ 624 } \ 625 } 626 627 628 #define CELLTYPECHK2( errHandling, modname, dtype, \ 629 cellPtr1, cellPtr2 ) \ 630 \ 631 CELLTYPECHK( errHandling, modname, dtype, cellPtr1 ); \ 632 CELLTYPECHK( errHandling, modname, dtype, cellPtr2 ); 633 634 635 636 #define CELLTYPECHK2_VAL( errHandling, modname, dtype, \ 637 cellPtr1, cellPtr2, retval ) \ 638 \ 639 CELLTYPECHK_VAL( errHandling, modname, dtype, cellPtr1, \ 640 retval ); \ 641 CELLTYPECHK_VAL( errHandling, modname, dtype, cellPtr2, \ 642 retval ); 643 644 645 646 #define CELLTYPECHK3( errHandling, modname, dtype, \ 647 cellPtr1, cellPtr2, cellPtr3 ) \ 648 \ 649 CELLTYPECHK( errHandling, modname, dtype, cellPtr1 ); \ 650 CELLTYPECHK( errHandling, modname, dtype, cellPtr2 ); \ 651 CELLTYPECHK( errHandling, modname, dtype, cellPtr3 ); 652 653 654 #define CELLTYPECHK3_VAL( errHandling, modname, dtype, \ 655 cellPtr1, cellPtr2, cellPtr3, \ 656 retval ) \ 657 \ 658 CELLTYPECHK_VAL( errHandling, modname, dtype, cellPtr1, \ 659 retval ); \ 660 CELLTYPECHK_VAL( errHandling, modname, dtype, cellPtr2, \ 661 retval ); \ 662 CELLTYPECHK_VAL( errHandling, modname, dtype, cellPtr3, \ 663 retval ); 664 665 666 667 #define CELLMATCH2( errHandling, modname, cellPtr1, cellPtr2 ) \ 668 \ 669 if ( (cellPtr1)->dtype != (cellPtr2)->dtype ) \ 670 { \ 671 SpiceChar * typstr[3] = \ 672 { \ 673 "character", "double precision", "integer" \ 674 }; \ 675 \ 676 if ( (errHandling) == CHK_DISCOVER ) \ 677 { \ 678 chkin_c ( modname ); \ 679 } \ 680 \ 681 setmsg_c ( "Data type of # is #; data type of # " \ 682 "is #, but types must match." ); \ 683 errch_c ( "#", (#cellPtr1) ); \ 684 errch_c ( "#", typstr[ (cellPtr1)->dtype ] ); \ 685 errch_c ( "#", (#cellPtr2) ); \ 686 errch_c ( "#", typstr[ (cellPtr2)->dtype ] ); \ 687 sigerr_c ( "SPICE(TYPEMISMATCH)" ); \ 688 \ 689 if ( ( (errHandling) == CHK_DISCOVER ) \ 690 || ( (errHandling) == CHK_STANDARD ) ) \ 691 { \ 692 chkout_c ( modname ); \ 693 return; \ 694 } \ 695 } 696 697 #define CELLMATCH2_VAL( errHandling, modname, \ 698 cellPtr1, cellPtr2, retval ) \ 699 \ 700 if ( (cellPtr1)->dtype != (cellPtr2)->dtype ) \ 701 { \ 702 SpiceChar * typstr[3] = \ 703 { \ 704 "character", "double precision", "integer" \ 705 }; \ 706 \ 707 if ( (errHandling) == CHK_DISCOVER ) \ 708 { \ 709 chkin_c ( modname ); \ 710 } \ 711 \ 712 setmsg_c ( "Data type of # is #; data type of # " \ 713 "is #, but types must match." ); \ 714 errch_c ( "#", (#cellPtr1) ); \ 715 errch_c ( "#", typstr [ (cellPtr1)->dtype ] ); \ 716 errch_c ( "#", (#cellPtr2) ); \ 717 errch_c ( "#", typstr [ (cellPtr2)->dtype ] ); \ 718 sigerr_c ( "SPICE(TYPEMISMATCH)" ); \ 719 \ 720 if ( ( (errHandling) == CHK_DISCOVER ) \ 721 || ( (errHandling) == CHK_STANDARD ) ) \ 722 { \ 723 chkout_c ( modname ); \ 724 return ( retval ); \ 725 } \ 726 } 727 728 729 #define CELLMATCH3( errHandling, modname, \ 730 cellPtr1, cellPtr2, cellPtr3 ) \ 731 \ 732 CELLMATCH2 ( errHandling, modname, cellPtr1, cellPtr2 ); \ 733 CELLMATCH2 ( errHandling, modname, cellPtr2, cellPtr3 ); 734 735 736 737 738 #define CELLMATCH3_VAL( errHandling, modname, cellPtr1, \ 739 cellPtr2, cellPtr3, retval ) \ 740 \ 741 CELLMATCH2_VAL ( errHandling, modname, \ 742 cellPtr1, cellPtr2, retval ); \ 743 \ 744 CELLMATCH2_VAL ( errHandling, modname, \ 745 cellPtr2, cellPtr3, retval ); 746 747 /* 748 Set checking macros: 749 */ 750 #define CELLISSETCHK( errHandling, modname, cellPtr1 ) \ 751 \ 752 if ( !(cellPtr1)->isSet ) \ 753 { \ 754 if ( (errHandling) == CHK_DISCOVER ) \ 755 { \ 756 chkin_c ( modname ); \ 757 } \ 758 \ 759 setmsg_c ( "Cell # must be sorted and have unique " \ 760 "values in order to be a CSPICE set. " \ 761 "The isSet flag in this cell is SPICEFALSE, " \ 762 "indicating the cell may have been modified " \ 763 "by a routine that doesn't preserve these " \ 764 "properties." ); \ 765 errch_c ( "#", (#cellPtr1) ); \ 766 sigerr_c ( "SPICE(NOTASET)" ); \ 767 \ 768 if ( ( (errHandling) == CHK_DISCOVER ) \ 769 || ( (errHandling) == CHK_STANDARD ) ) \ 770 { \ 771 chkout_c ( modname ); \ 772 return; \ 773 } \ 774 } 775 776 777 #define CELLISSETCHK_VAL( errHandling, modname, \ 778 cellPtr1, retval ) \ 779 \ 780 if ( !(cellPtr1)->isSet ) \ 781 { \ 782 if ( (errHandling) == CHK_DISCOVER ) \ 783 { \ 784 chkin_c ( modname ); \ 785 } \ 786 \ 787 setmsg_c ( "Cell # must be sorted and have unique " \ 788 "values in order to be a CSPICE set. " \ 789 "The isSet flag in this cell is SPICEFALSE, " \ 790 "indicating the cell may have been modified " \ 791 "by a routine that doesn't preserve these " \ 792 "properties." ); \ 793 errch_c ( "#", (#cellPtr1) ); \ 794 sigerr_c ( "SPICE(NOTASET)" ); \ 795 \ 796 if ( ( (errHandling) == CHK_DISCOVER ) \ 797 || ( (errHandling) == CHK_STANDARD ) ) \ 798 { \ 799 chkout_c ( modname ); \ 800 return (retval); \ 801 } \ 802 } 803 804 805 #define CELLISSETCHK2( errHandling, modname, \ 806 cellPtr1, cellPtr2 ) \ 807 \ 808 CELLISSETCHK( errHandling, modname, cellPtr1 ); \ 809 CELLISSETCHK( errHandling, modname, cellPtr2 ); 810 811 812 813 #define CELLISSETCHK2_VAL( errHandling, modname, \ 814 cellPtr1, cellPtr2, retval ) \ 815 \ 816 CELLISSETCHK_VAL( errHandling, modname, cellPtr1, retval ); \ 817 CELLISSETCHK_VAL( errHandling, modname, cellPtr2, retval ); \ 818 819 820 821 #define CELLISSETCHK3( errHandling, modname, \ 822 cellPtr1, cellPtr2, cellPtr3 ) \ 823 \ 824 CELLISSETCHK ( errHandling, modname, cellPtr1 ); \ 825 CELLISSETCHK ( errHandling, modname, cellPtr2 ); \ 826 CELLISSETCHK ( errHandling, modname, cellPtr3 ); 827 828 829 #define CELLISSETCHK3_VAL( errHandling, modname, cellPtr1, \ 830 cellPtr2, cellPtr3, retval ) \ 831 \ 832 CELLISSETCHK_VAL ( errHandling, modname, cellPtr1, retval ); \ 833 CELLISSETCHK_VAL ( errHandling, modname, cellPtr2, retval ); \ 834 CELLISSETCHK_VAL ( errHandling, modname, cellPtr3, retval ); 835 836 837 /* 838 C-to-Fortran and Fortran-to-C character cell translation macros: 839 */ 840 841 /* 842 Macros that map one or more character C cells to dynamically 843 allocated Fortran-style character cells: 844 */ 845 #define C2F_MAP_CELL( caller, CCell, fCell, fLen ) \ 846 \ 847 { \ 848 /* \ 849 fCell and fLen are to be passed by reference, as if this \ 850 macro were a function. \ 851 \ 852 \ 853 Caution: dynamically allocates array fCell, which is to be \ 854 freed by caller! \ 855 */ \ 856 SpiceInt ndim; \ 857 SpiceInt lenvals; \ 858 \ 859 \ 860 ndim = (CCell)->size + SPICE_CELL_CTRLSZ; \ 861 lenvals = (CCell)->length; \ 862 \ 863 C2F_MapFixStrArr ( (caller), ndim, lenvals, \ 864 (CCell)->base, (fLen), (fCell) ); \ 865 \ 866 if ( !failed_c() ) \ 867 { \ 868 /* \ 869 Explicitly set the control area info in the Fortran cell.\ 870 */ \ 871 ssizec_ ( ( integer * ) &((CCell)->size), \ 872 ( char * ) *(fCell), \ 873 ( ftnlen ) *(fLen) ); \ 874 \ 875 scardc_ ( ( integer * ) &((CCell)->card), \ 876 ( char * ) *(fCell), \ 877 ( ftnlen ) *(fLen) ); \ 878 \ 879 if ( failed_c() ) \ 880 { \ 881 /* \ 882 Setting size or cardinality of the Fortran cell \ 883 can fail, for example if the cell's string length \ 884 is too short. \ 885 */ \ 886 free ( *(fCell) ); \ 887 } \ 888 } \ 889 } 890 891 892 #define C2F_MAP_CELL2( caller, CCell1, fCell1, fLen1, \ 893 CCell2, fCell2, fLen2 ) \ 894 \ 895 { \ 896 C2F_MAP_CELL( caller, CCell1, fCell1, fLen1 ); \ 897 \ 898 if ( !failed_c() ) \ 899 { \ 900 C2F_MAP_CELL( caller, CCell2, fCell2, fLen2 ); \ 901 \ 902 if ( failed_c() ) \ 903 { \ 904 free ( *(fCell1) ); \ 905 } \ 906 } \ 907 } 908 909 910 #define C2F_MAP_CELL3( caller, CCell1, fCell1, fLen1, \ 911 CCell2, fCell2, fLen2, \ 912 CCell3, fCell3, fLen3 ) \ 913 \ 914 { \ 915 C2F_MAP_CELL2( caller, CCell1, fCell1, fLen1, \ 916 CCell2, fCell2, fLen2 ); \ 917 \ 918 if ( !failed_c() ) \ 919 { \ 920 C2F_MAP_CELL( caller, CCell3, fCell3, fLen3 ); \ 921 \ 922 if ( failed_c() ) \ 923 { \ 924 free ( *(fCell1) ); \ 925 free ( *(fCell2) ); \ 926 } \ 927 } \ 928 } 929 930 931 932 /* 933 Macro that maps a Fortran-style character cell to a C cell 934 (Note: this macro frees the Fortran cell): 935 */ 936 937 #define F2C_MAP_CELL( fCell, fLen, CCell ) \ 938 \ 939 { \ 940 SpiceInt card; \ 941 SpiceInt lenvals; \ 942 SpiceInt ndim; \ 943 SpiceInt nBytes; \ 944 SpiceInt size; \ 945 void * array; \ 946 \ 947 ndim = (CCell)->size + SPICE_CELL_CTRLSZ; \ 948 lenvals = (CCell)->length; \ 949 array = (CCell)->base; \ 950 \ 951 /* \ 952 Capture the size and cardinality of the Fortran cell. \ 953 */ \ 954 if ( !failed_c() ) \ 955 { \ 956 size = sizec_ ( ( char * ) (fCell), \ 957 ( ftnlen ) fLen ); \ 958 \ 959 card = cardc_ ( ( char * ) (fCell), \ 960 ( ftnlen ) fLen ); \ 961 } \ 962 \ 963 \ 964 /* \ 965 Copy the Fortran array into the output array. \ 966 */ \ 967 \ 968 nBytes = ndim * fLen * sizeof(SpiceChar); \ 969 memmove ( array, fCell, nBytes ); \ 970 /* \ 971 Convert the output array from Fortran to C style. \ 972 */ \ 973 F2C_ConvertTrStrArr ( ndim, lenvals, (SpiceChar *)array ); \ 974 \ 975 /* \ 976 Sync the size and cardinality of the C cell. \ 977 */ \ 978 if ( !failed_c() ) \ 979 { \ 980 (CCell)->size = size; \ 981 (CCell)->card = card; \ 982 } \ 983 } 984 985 986 987 /* 988 End of header SpiceZmc.h 989 */ 990