1 /*
2 
3 -Procedure union_c ( Union of two sets )
4 
5 -Abstract
6 
7    Compute the union of two sets of any data type to form a third set.
8 
9 -Disclaimer
10 
11    THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE
12    CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S.
13    GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE
14    ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE
15    PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS"
16    TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY
17    WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A
18    PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC
19    SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
20    SOFTWARE AND RELATED MATERIALS, HOWEVER USED.
21 
22    IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA
23    BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT
24    LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND,
25    INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS,
26    REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE
27    REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY.
28 
29    RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF
30    THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY
31    CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE
32    ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE.
33 
34 -Required_Reading
35 
36    SETS
37 
38 -Keywords
39 
40    CELLS, SETS
41 
42 */
43 
44    #include "SpiceUsr.h"
45    #include "SpiceZfc.h"
46    #include "SpiceZst.h"
47    #include "SpiceZmc.h"
48 
union_c(SpiceCell * a,SpiceCell * b,SpiceCell * c)49    void union_c (  SpiceCell   * a,
50                    SpiceCell   * b,
51                    SpiceCell   * c  )
52 
53 /*
54 
55 -Brief_I/O
56 
57    VARIABLE  I/O  DESCRIPTION
58    --------  ---  --------------------------------------------------
59    a          I   First input set.
60    b          I   Second input set.
61    c          O   Union of a and b.
62 
63 -Detailed_Input
64 
65    a           is a CSPICE set.  a must be declared as a SpiceCell
66                of data type character, double precision, or integer.
67 
68    b           is a CSPICE set, distinct from a.  b must have the
69                same data type as a.
70 
71 -Detailed_Output
72 
73    c           is a CSPICE set, distinct from sets a and b, which
74                contains the union of a and b (that is, all of
75                the elements which are in a or b or both).  c must
76                have the same data type as a and b.
77 
78                When comparing elements of character sets, this routine
79                ignores trailing blanks.  Trailing blanks will be
80                trimmed from the members of the output set c.
81 
82 -Parameters
83 
84    None.
85 
86 -Exceptions
87 
88    1) If the input set arguments don't have identical data types,
89       the error SPICE(TYPEMISMATCH) is signaled.
90 
91    2) If the union of the two sets contains more elements than can be
92       contained in the output set, the error SPICE(SETEXCESS) is signaled.
93 
94    3) If the set arguments have character type and the length of the
95       elements of the output set is less than the maximum of the
96       lengths of the elements of the input sets, the error
97       SPICE(ELEMENTSTOOSHORT) is signaled.
98 
99    4) If either of the input arguments may be unordered or contain
100       duplicates, the error SPICE(NOTASET) is signaled.
101 
102 -Files
103 
104    None.
105 
106 -Particulars
107 
108    This is a generic CSPICE set routine; it operates on sets of any
109    supported data type.
110 
111    The union of two sets contains every element which is
112    in the first set, or in the second set, or in both sets.
113 
114       {a,b}      union  {c,d}     =  {a,b,c,d}
115       {a,b,c}           {b,c,d}      {a,b,c,d}
116       {a,b,c,d}         {}           {a,b,c,d}
117       {}                {a,b,c,d}    {a,b,c,d}
118       {}                {}           {}
119 
120 -Examples
121 
122    1) The following code fragment places the union of the character sets
123       planets and asteroids into the character set result.
124 
125 
126          #include "SpiceUsr.h"
127                 .
128                 .
129                 .
130          /.
131          Declare the sets with string length NAMLEN and with maximum
132          number of elements MAXSIZ.
133          ./
134          SPICECHAR_CELL ( planets,   MAXSIZ, NAMLEN );
135          SPICECHAR_CELL ( asteroids, MAXSIZ, NAMLEN );
136          SPICECHAR_CELL ( result,    MAXSIZ, NAMLEN );
137                 .
138                 .
139                 .
140          /.
141          Compute the union.
142          ./
143          union_c ( &planets, &asteroids, &result );
144 
145 
146    2) Repeat example #1, this time using integer sets containing
147       ID codes of the bodies of interest.
148 
149 
150          #include "SpiceUsr.h"
151                 .
152                 .
153                 .
154          /.
155          Declare the sets with maximum number of elements MAXSIZ.
156          ./
157          SPICEINT_CELL ( planets,   MAXSIZ );
158          SPICEINT_CELL ( asteroids, MAXSIZ );
159          SPICEINT_CELL ( result,    MAXSIZ );
160                 .
161                 .
162                 .
163          /.
164          Compute the union.
165          ./
166          union_c ( &planets, &asteroids, &result );
167 
168 
169    3) Construct a set containing the periapse and apoapse TDB epochs
170       of an orbiter, given two separate sets containing the epochs of
171       those events.
172 
173 
174          #include "SpiceUsr.h"
175                 .
176                 .
177                 .
178          /.
179          Declare the sets with maximum number of elements MAXSIZ.
180          ./
181          SPICEDOUBLE_CELL ( periapse,   MAXSIZ );
182          SPICEDOUBLE_CELL ( apoapse,    MAXSIZ );
183          SPICEDOUBLE_CELL ( result,     MAXSIZ );
184                 .
185                 .
186                 .
187          /.
188          Compute the union.
189          ./
190          union_c ( &periapse, &apoapse, &result );
191 
192 
193 -Restrictions
194 
195    1) The output set must be distinct from both of the input sets.
196       For example, the following calls are invalid.
197 
198          union_c  ( &current,  &new,      &current );
199          union_c  ( &new,      &current,  &current );
200 
201       In each of the examples above, whether or not the subroutine
202       signals an error, the results will almost certainly be wrong.
203       Nearly the same effect can be achieved, however, by placing the
204       result into a temporary set, which is immediately copied back
205       into one of the input sets, as shown below.
206 
207          union_c  ( &current,  &new,  &temp );
208          copy_c   ( &temp,     &new         );
209 
210 
211    2) String comparisons performed by this routine are Fortran-style:
212       trailing blanks in the input sets are ignored. This gives
213       consistent behavior with CSPICE code generated by the f2c
214       translator, as well as with the Fortran SPICE Toolkit.
215 
216       Note that this behavior is not identical to that of the ANSI
217       C library functions strcmp and strncmp.
218 
219 -Literature_References
220 
221    None.
222 
223 -Author_and_Institution
224 
225    N.J. Bachman    (JPL)
226    C.A. Curzon     (JPL)
227    W.L. Taber      (JPL)
228    I.M. Underwood  (JPL)
229 
230 -Version
231 
232    -CSPICE Version 1.1.0, 15-FEB-2005 (NJB)
233 
234        Bug fix:  loop bound changed from 2 to 3 in loop used
235        to free dynamically allocated arrays.
236 
237    -CSPICE Version 1.0.0, 08-AUG-2002 (NJB) (CAC) (WLT) (IMU)
238 
239 -Index_Entries
240 
241    union of two sets
242 
243 -&
244 */
245 
246 
247 { /* Begin union_c */
248 
249 
250    /*
251    Local variables
252    */
253    SpiceChar             * fCell[3];
254 
255    SpiceInt                fLen [3];
256    SpiceInt                i;
257 
258 
259    /*
260    Standard SPICE error handling.
261    */
262    if ( return_c() )
263    {
264       return;
265    }
266 
267    chkin_c ( "union_c" );
268 
269    /*
270    Make sure data types match.
271    */
272    CELLMATCH3 ( CHK_STANDARD, "union_c", a, b, c );
273 
274    /*
275    Make sure the input cells are sets.
276    */
277    CELLISSETCHK2 ( CHK_STANDARD, "union_c", a, b );
278 
279    /*
280    Initialize the cells if necessary.
281    */
282    CELLINIT3 ( a, b, c );
283 
284    /*
285    Call the union routine appropriate for the data type of the cells.
286    */
287    if ( a->dtype == SPICE_CHR )
288    {
289 
290       /*
291       Construct Fortran-style sets suitable for passing to unionc_.
292       */
293       C2F_MAP_CELL3 (  "",
294                        a, fCell,   fLen,
295                        b, fCell+1, fLen+1,
296                        c, fCell+2, fLen+2  );
297 
298 
299       if ( failed_c() )
300       {
301          chkout_c ( "union_c" );
302          return;
303       }
304 
305 
306       unionc_ ( (char    * )  fCell[0],
307                 (char    * )  fCell[1],
308                 (char    * )  fCell[2],
309                 (ftnlen    )  fLen[0],
310                 (ftnlen    )  fLen[1],
311                 (ftnlen    )  fLen[2]  );
312 
313       /*
314       Map the union back to a C style cell.
315       */
316       F2C_MAP_CELL ( fCell[2], fLen[2], c );
317 
318 
319       /*
320       We're done with the dynamically allocated Fortran-style arrays.
321       */
322       for ( i = 0;  i < 3;  i++ )
323       {
324          free ( fCell[i] );
325       }
326 
327    }
328 
329    else if ( a->dtype == SPICE_DP )
330    {
331       uniond_ ( (doublereal * )  (a->base),
332                 (doublereal * )  (b->base),
333                 (doublereal * )  (c->base)  );
334       /*
335       Sync the output cell.
336       */
337       if ( !failed_c() )
338       {
339          zzsynccl_c ( F2C, c );
340       }
341 
342    }
343 
344    else if ( a->dtype == SPICE_INT )
345    {
346       unioni_ ( (integer * )  (a->base),
347                 (integer * )  (b->base),
348                 (integer * )  (c->base)  );
349 
350       /*
351       Sync the output cell.
352       */
353       if ( !failed_c() )
354       {
355          zzsynccl_c ( F2C, c );
356       }
357    }
358 
359    else
360    {
361      setmsg_c ( "Cell a contains unrecognized data type code #." );
362      errint_c ( "#",  (SpiceInt) (a->dtype)                      );
363      sigerr_c ( "SPICE(NOTSUPPORTED)"                            );
364      chkout_c ( "union_c"                                        );
365      return;
366    }
367 
368 
369    /*
370    Indicate the result is a set.
371    */
372    c->isSet = SPICETRUE;
373 
374 
375    chkout_c ( "union_c" );
376 
377 } /* End union_c */
378