1 /*
2 
3 -Procedure reordc_c ( Reorder a character array )
4 
5 -Abstract
6 
7    Re-order the elements of an array of character strings
8    according to a given order vector.
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    None.
38 
39 -Keywords
40 
41    ARRAY,  SORT
42 
43 */
44 
45    #include <stdlib.h>
46    #include "SpiceUsr.h"
47    #include "SpiceZfc.h"
48    #include "SpiceZst.h"
49    #include "SpiceZmc.h"
50    #include "SpiceZim.h"
51    #undef    reordc_c
52 
53 
reordc_c(ConstSpiceInt * iorder,SpiceInt ndim,SpiceInt lenvals,void * array)54    void reordc_c ( ConstSpiceInt  * iorder,
55                    SpiceInt         ndim,
56                    SpiceInt         lenvals,
57                    void           * array    )
58 
59 /*
60 
61 -Brief_I/O
62 
63    VARIABLE  I/O  DESCRIPTION
64    --------  ---  --------------------------------------------------
65    iorder     I   Order vector to be used to re-order array.
66    ndim       I   Dimension of array.
67    lenvals    I   String length.
68    array     I/O  Array to be re-ordered.
69 
70 -Detailed_Input
71 
72    iorder      is the order vector to be used to re-order the input
73                array. The first element of iorder is the index of
74                the first item of the re-ordered array, and so on.
75 
76                Note that the order imposed by reordc_c is not the
77                same order that would be imposed by a sorting
78                routine. In general, the order vector will have
79                been created (by one of the order routines) for
80                a related array, as illustrated in the example below.
81 
82                The elements of iorder range from zero to ndim-1.
83 
84    ndim        is the number of elements in the input array.
85 
86    lenvals     is the declared length of the strings in the input
87                string array, including null terminators.  The input
88                array should be declared with dimension
89 
90                   [ndim][lenvals]
91 
92    array       on input, is an array containing some number of
93                elements in unspecified order.
94 
95 -Detailed_Output
96 
97    array       on output, is the same array, with the elements
98                in re-ordered as specified by iorder.
99 
100 -Parameters
101 
102    None.
103 
104 -Exceptions
105 
106    1) If the input string array pointer is null, the error
107       SPICE(NULLPOINTER) will be signaled.
108 
109    2) If the input array string's length is less than 2, the error
110       SPICE(STRINGTOOSHORT) will be signaled.
111 
112    3) If memory cannot be allocated to create a Fortran-style version of
113       the input order vector, the error SPICE(MALLOCFAILED) is signaled.
114 
115    4) If ndim < 2, this routine executes a no-op.  This case is
116       not an error.
117 
118 -Files
119 
120    None.
121 
122 -Particulars
123 
124    reordc_c uses a cyclical algorithm to re-order the elements of
125    the array in place. After re-ordering, element iorder[0] of
126    the input array is the first element of the output array,
127    element iorder[1] of the input array is the second element of
128    the output array, and so on.
129 
130    The order vector used by reordc_c is typically created for
131    a related array by one of the order*_c routines, as shown in
132    the example below.
133 
134 -Examples
135 
136    In the following example, the order*_c and reord*_c routines are
137    used to sort four related arrays (containing the names,
138    masses, integer ID codes, and visual magnitudes for a group
139    of satellites). This is representative of the typical use of
140    these routines.
141 
142       #include "SpiceUsr.h"
143            .
144            .
145            .
146       /.
147       Sort the object arrays by name.
148       ./
149 
150       orderc_c ( namlen, names, n,  iorder );
151 
152       reordc_c ( iorder, n, namlen, names  );
153       reordd_c ( iorder, n,         masses );
154       reordi_c ( iorder, n,         codes  );
155       reordd_c ( iorder, n,         vmags  );
156 
157 -Restrictions
158 
159    None.
160 
161 -Author_and_Institution
162 
163    N.J. Bachman    (JPL)
164    W.L. Taber      (JPL)
165    I.M. Underwood  (JPL)
166 
167 -Literature_References
168 
169    None.
170 
171 -Version
172 
173    -CSPICE Version 1.0.0, 10-JUL-2002 (NJB) (WLT) (IMU)
174 
175 -Index_Entries
176 
177    reorder a character array
178 
179 -&
180 */
181 
182 { /* Begin reordc_c */
183 
184    /*
185    Local variables
186    */
187    SpiceChar             * fCvalsArr;
188 
189    SpiceInt                fCvalsLen;
190    SpiceInt                i;
191    SpiceInt              * ordvec ;
192    SpiceInt                vSize;
193 
194 
195 
196    /*
197    If the input array doesn't have at least two elements, return
198    immediately.
199    */
200    if ( ndim < 2 )
201    {
202       return;
203    }
204 
205    /*
206    Use discovery check-in.
207 
208 
209    Make sure the input pointer for the string array is non-null
210    and that the length lenvals is sufficient.
211    */
212    CHKOSTR ( CHK_DISCOVER, "reordc_c", array, lenvals );
213 
214 
215    /*
216    Create a Fortran-style string array.
217    */
218    C2F_MapStrArr ( "reordc_c",
219                    ndim, lenvals, array, &fCvalsLen, &fCvalsArr );
220 
221    if ( failed_c() )
222    {
223       return;
224    }
225 
226 
227    /*
228    Get a local copy of the input order vector; map the vector's contents
229    to the range 1:ndim.
230    */
231    vSize  = ndim * sizeof(SpiceInt);
232 
233    ordvec = (SpiceInt *) malloc( vSize );
234 
235    if ( ordvec == 0 )
236    {
237       free ( fCvalsArr );
238 
239       chkin_c  ( "reordc_c"                                );
240       setmsg_c ( "Failure on malloc call to create array "
241                  "for Fortran-style order vector.  Tried "
242                  "to allocate # bytes."                    );
243       errint_c ( "#",  vSize                               );
244       sigerr_c ( "SPICE(MALLOCFAILED)"                     );
245       chkout_c ( "reordc_c"                                );
246       return;
247    }
248 
249    for ( i = 0;  i < ndim;  i++ )
250    {
251       ordvec[i] = iorder[i] + 1;
252    }
253 
254 
255    /*
256    Call the f2c'd routine.
257    */
258    reordc_ (  ( integer    * ) ordvec,
259               ( integer    * ) &ndim,
260               ( char       * ) fCvalsArr,
261               ( ftnlen       ) fCvalsLen  );
262 
263    /*
264    Free the dynamically allocated arrays.
265    */
266    free ( fCvalsArr );
267    free ( ordvec    );
268 
269 
270 } /* End reordc_c */
271