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