1 /* 2 3 -Procedure lstlec_c ( Last character element less than or equal to. ) 4 5 -Abstract 6 7 Given a character string and an ordered array of character 8 strings, find the index of the largest array element less than 9 or equal to the given string. 10 11 -Disclaimer 12 13 THIS SOFTWARE AND ANY RELATED MATERIALS WERE CREATED BY THE 14 CALIFORNIA INSTITUTE OF TECHNOLOGY (CALTECH) UNDER A U.S. 15 GOVERNMENT CONTRACT WITH THE NATIONAL AERONAUTICS AND SPACE 16 ADMINISTRATION (NASA). THE SOFTWARE IS TECHNOLOGY AND SOFTWARE 17 PUBLICLY AVAILABLE UNDER U.S. EXPORT LAWS AND IS PROVIDED "AS-IS" 18 TO THE RECIPIENT WITHOUT WARRANTY OF ANY KIND, INCLUDING ANY 19 WARRANTIES OF PERFORMANCE OR MERCHANTABILITY OR FITNESS FOR A 20 PARTICULAR USE OR PURPOSE (AS SET FORTH IN UNITED STATES UCC 21 SECTIONS 2312-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE 22 SOFTWARE AND RELATED MATERIALS, HOWEVER USED. 23 24 IN NO EVENT SHALL CALTECH, ITS JET PROPULSION LABORATORY, OR NASA 25 BE LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING, BUT NOT 26 LIMITED TO, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, 27 INCLUDING ECONOMIC DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, 28 REGARDLESS OF WHETHER CALTECH, JPL, OR NASA BE ADVISED, HAVE 29 REASON TO KNOW, OR, IN FACT, SHALL KNOW OF THE POSSIBILITY. 30 31 RECIPIENT BEARS ALL RISK RELATING TO QUALITY AND PERFORMANCE OF 32 THE SOFTWARE AND ANY RELATED MATERIALS, AND AGREES TO INDEMNIFY 33 CALTECH AND NASA FOR ALL THIRD-PARTY CLAIMS RESULTING FROM THE 34 ACTIONS OF RECIPIENT IN THE USE OF THE SOFTWARE. 35 36 -Required_Reading 37 38 None. 39 40 -Keywords 41 42 SEARCH, ARRAY 43 44 */ 45 46 #include "SpiceUsr.h" 47 #include "SpiceZfc.h" 48 #include "SpiceZst.h" 49 #include "SpiceZmc.h" 50 #include "f2cMang.h" 51 #undef lstlec_c 52 lstlec_c(ConstSpiceChar * string,SpiceInt n,SpiceInt lenvals,const void * array)53 SpiceInt lstlec_c ( ConstSpiceChar * string, 54 SpiceInt n, 55 SpiceInt lenvals, 56 const void * array ) 57 /* 58 59 -Brief_I/O 60 61 VARIABLE I/O DESCRIPTION 62 -------- --- -------------------------------------------------- 63 string I Upper bound value to search against. 64 n I Number elements in array. 65 lenvals I String length. 66 array I Array of possible lower bounds. 67 68 The function returns the index of the last element of array that 69 is lexically less than or equal to string. 70 71 -Detailed_Input 72 73 string is a string acting as an upper bound: the array element 74 that is lexically the greatest element less than or 75 equal to string is to be found. Trailing blanks in this 76 bound value are not significant. 77 78 n is the dimension of the array. 79 80 lenvals is the declared length of the strings in the input 81 string array, including null terminators. The input 82 array should be declared with dimension 83 84 [n][lenvals] 85 86 array is the array of character strings to be searched. 87 Trailing blanks in the strings in this array are not 88 significant. The strings must be sorted in 89 non-decreasing order. The elements of array need not be 90 distinct. 91 92 93 -Detailed_Output 94 95 The function returns the index of the highest-indexed element in the 96 input array that is less than or equal to string. The routine assumes 97 the array elements are sorted in non-decreasing order. 98 99 If all elements of the input array are greater than the specified 100 upper bound string, the function returns -1. 101 102 -Parameters 103 104 None. 105 106 -Exceptions 107 108 1) If ndim < 1 the function value is -1. This is not considered 109 an error. 110 111 2) If input key value pointer is null, the error SPICE(NULLPOINTER) will 112 be signaled. The function returns -1. 113 114 3) The input key value may have length zero. This case is not 115 considered an error. 116 117 4) If the input array pointer is null, the error SPICE(NULLPOINTER) will 118 be signaled. The function returns -1. 119 120 5) If the input array string's length is less than 2, the error 121 SPICE(STRINGTOOSHORT) will be signaled. The function returns -1. 122 123 -Files 124 125 None. 126 127 -Particulars 128 129 Note: If you need to find the first element of the array that is 130 greater than string, simply add 1 to the result returned by 131 this function and check to see if the result is within the 132 array bounds given by n. 133 134 -Examples 135 136 Let array be a character array of dimension 137 138 [5][lenvals] 139 140 which contains the following elements: 141 142 "BOHR" 143 "EINSTEIN" 144 "FEYNMAN" 145 "GALILEO" 146 "NEWTON" 147 148 Then 149 150 lstlec_c ( "NEWTON", 5, lenvals, array ) == 4 151 lstlec_c ( "EINSTEIN", 5, lenvals, array ) == 1 152 lstlec_c ( "GALILEO", 5, lenvals, array ) == 3 153 lstlec_c ( "Galileo", 5, lenvals, array ) == 3 154 lstlec_c ( "BETHE", 5, lenvals, array ) == -1 155 156 -Restrictions 157 158 1) The input array is assumed to be sorted in increasing order. If 159 this condition is not met, the results of bsrchc_c are unpredictable. 160 161 2) String comparisons performed by this routine are Fortran-style: 162 trailing blanks in the input array or key value are ignored. 163 This gives consistent behavior with CSPICE code generated by 164 the f2c translator, as well as with the Fortran SPICE Toolkit. 165 166 Note that this behavior is not identical to that of the ANSI 167 C library functions strcmp and strncmp. 168 169 -Literature_References 170 171 None. 172 173 -Author_and_Institution 174 175 N.J. Bachman (JPL) 176 H.A. Neilan (JPL) 177 W.L. Taber (JPL) 178 179 -Version 180 181 -CSPICE Version 1.0.0, 22-JUL-2002 (NJB) (HAN) (WLT) 182 183 -Index_Entries 184 185 last character element less_than_or_equal_to 186 187 -& 188 */ 189 190 { /* Begin lstlec_c */ 191 192 193 /* 194 f2c library utility prototypes 195 */ 196 logical l_ge (char *a, char *b, ftnlen la, ftnlen lb ); 197 logical l_le (char *a, char *b, ftnlen la, ftnlen lb ); 198 logical l_lt (char *a, char *b, ftnlen la, ftnlen lb ); 199 200 /* 201 Local macros 202 */ 203 #define ARRAY( i ) ( ( (SpiceChar *)array ) + (i)*lenvals ) 204 205 206 /* 207 Local variables 208 */ 209 SpiceInt begin; 210 SpiceInt end; 211 SpiceInt items; 212 SpiceInt j; 213 SpiceInt keylen; 214 SpiceInt middle; 215 216 217 218 /* 219 Use discovery check-in. 220 221 Return immediately if the array dimension is non-positive. 222 */ 223 if ( n < 1 ) 224 { 225 return ( -1 ); 226 } 227 228 /* 229 Make sure the pointer for the key value is non-null 230 and that the length is adequate. 231 */ 232 CHKPTR_VAL ( CHK_DISCOVER, "lstlec_c", string, -1 ); 233 234 235 /* 236 Make sure the pointer for the string array is non-null 237 and that the length lenvals is sufficient. 238 */ 239 CHKOSTR_VAL ( CHK_DISCOVER, "lstlec_c", array, lenvals, -1 ); 240 241 242 /* 243 Return if none of the array's elements are less than or equal to 244 the key value. 245 */ 246 keylen = strlen(string); 247 248 begin = 0; 249 end = n - 1; 250 251 if ( l_lt( ( char * )string, 252 ( char * )ARRAY(begin), 253 ( ftnlen )keylen, 254 ( ftnlen )strlen(ARRAY(begin)) ) ) 255 { 256 return ( -1 ); 257 } 258 259 260 /* 261 Return if the key string is greater than or equal to 262 all of the array's elements. 263 */ 264 if ( l_ge( ( char * )string, 265 ( char * )ARRAY(end), 266 ( ftnlen )keylen, 267 ( ftnlen )strlen(ARRAY(end)) ) ) 268 { 269 return ( end ); 270 } 271 272 273 /* 274 Do a binary search for the specified key value. 275 276 At this point, string is greater than or equal to the first element 277 of array and strictly less than the last element of array. 278 */ 279 items = n; 280 281 while ( items > 2 ) 282 { 283 /* 284 Check the middle element. 285 */ 286 j = items / 2; 287 middle = begin + j; 288 289 290 /* 291 Narrow the search area. 292 */ 293 if ( l_le ( (char * ) ARRAY(middle), 294 (char * ) string, 295 (ftnlen ) lenvals-1, 296 (ftnlen ) keylen ) ) 297 { 298 /* 299 The middle element is less than or equal to string. 300 */ 301 begin = middle; 302 } 303 else 304 { 305 end = middle; 306 } 307 308 items = end - begin + 1; 309 310 /* 311 At this point, string is greater than or equal to the array element 312 at index begin and strictly less than the element at index end. 313 */ 314 } 315 316 /* 317 The element at index begin is the winner. 318 */ 319 return ( begin ); 320 321 322 } /* End lstlec_c */ 323