1 /* 2 3 -Procedure eqstr_c ( Equivalent strings ) 4 5 -Abstract 6 7 Determine whether two strings are equivalent. 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 None. 37 38 -Keywords 39 40 ALPHANUMERIC 41 ASCII 42 CHARACTER 43 COMPARE 44 PARSING 45 SEARCH 46 STRING 47 TEXT 48 49 */ 50 #include <ctype.h> 51 #include "SpiceUsr.h" 52 #include "SpiceZmc.h" 53 54 eqstr_c(ConstSpiceChar * a,ConstSpiceChar * b)55 SpiceBoolean eqstr_c ( ConstSpiceChar * a, ConstSpiceChar * b ) 56 57 /* 58 59 -Brief_I/O 60 61 VARIABLE I/O DESCRIPTION 62 -------- --- -------------------------------------------------- 63 a, 64 b I Arbitrary character strings. 65 66 The function returns SPICETRUE if A and B are equivalent. 67 68 -Detailed_Input 69 70 a, 71 b are arbitrary character strings. 72 73 -Detailed_Output 74 75 The function returns TRUE if A and B are equivalent: that is, 76 if A and B contain the same characters in the same order, 77 when white space characters are ignored and uppercase and lowercase 78 characters are considered equal. 79 80 White space characters are those in the set 81 82 { ' ', '\f', '\n', '\r', '\t', '\v' } 83 84 Note that this specification differs from that of the Fortran version 85 of this routine, which considers the blank ( ' ' ) to be the only 86 white space character. 87 88 -Parameters 89 90 None. 91 92 -Files 93 94 None. 95 96 -Exceptions 97 98 1) If either input string pointer is null, the error 99 SPICE(NULLPOINTER) will be signaled. 100 101 102 -Particulars 103 104 This routine is provided for those cases in which two strings 105 must be compared, and in which allowances are to be made for 106 extra (leading, trailing, and embedded) blanks and differences 107 in case. For the most part, 108 109 if ( eqstr_c ( A, B ) ) 110 . 111 . 112 113 is true whenever 114 115 cmprss_c ( ' ', 0, a, MAXLEN, tempa ); 116 ucase_c ( tempa, MAXLEN, tempa ); 117 118 cmprss_c ( ' ', 0, b, MAXLEN, tempb ); 119 ucase_c ( tempb, MAXLEN, tempb ); 120 121 122 if ( !strcmp ( tempa, tempb ) ) 123 . 124 . 125 126 is true. There are two important differences, however. 127 128 1) The single reference to eqstr_c is much simpler to 129 write, and simpler to understand. 130 131 2) The reference to eqstr_c does not require any temporary 132 storage, nor does it require that the strings a and b 133 be changed. This feature is especially useful when 134 comparing strings recieved as subprogram arguments 135 against strings stored internally within the subprogram. 136 137 138 -Examples 139 140 141 Usage 142 -------------------------------------------- 143 144 All of the following are TRUE. 145 146 eqstr_c ( "A short string ", 147 "ashortstring" ); 148 149 eqstr_c ( "Embedded blanks", 150 "Em be dd ed bl an ks" ); 151 152 eqstr_c ( "Embedded blanks", 153 " Embeddedblanks" ); 154 155 eqstr_c ( " ", 156 " " ); 157 158 159 All of the following are FALSE. 160 161 eqstr_c ( "One word left out", 162 "WORD LEFT OUT" ); 163 164 eqstr_c ( "Extra [] delimiters", 165 "extradelimiters" ); 166 167 eqstr_c ( "Testing 1, 2, 3", 168 "TESTING123" ); 169 170 171 Use 172 -------------------------------------------- 173 174 The following illustrates a typical use for eqstr_c. 175 176 #include "SpiceUsr.h" 177 . 178 . 179 . 180 SpiceChar * greeting ( SpiceChar *who ) 181 { 182 183 if ( eqstr_c ( who, "Steve" ) ) 184 { 185 return ( "Yes, sir?" ); 186 } 187 else if ( eqstr_c ( who, "Chuck" ) ) 188 { 189 return ( "What can I do for you?" ); 190 } 191 else 192 { 193 return ( "Whaddya want?" ); 194 } 195 } 196 197 Note that all of the following calls will elicit the 198 greeting "Yes, sir?": 199 200 greeting ( "STEVE" ); 201 greeting ( "steve" ); 202 greeting ( "Steve" ); 203 greeting ( "sTEVE" ); 204 greeting ( " S T E V E " ); 205 206 -Restrictions 207 208 None. 209 210 -Literature_References 211 212 1) "American National Standard for Programming Languages -- C," 213 Published by the American National Standards Institute, 1990. 214 Section 7.3.1.9., p. 104. 215 216 -Author_and_Institution 217 218 N.J. Bachman (JPL) 219 I.M. Underwood (JPL) 220 221 -Version 222 223 -CSPICE Version 1.3.0, 27-AUG-1999 (NJB) 224 225 Added check for null input strings. Added logic to handle the 226 case where at least one input string is empty. 227 228 -CSPICE Version 1.2.0, 24-FEB-1999 (NJB) 229 230 Arguments passed to isspace are now cast to unsigned char to 231 suppress compilation warnings on some systems. 232 233 -CSPICE Version 1.1.0, 08-FEB-1998 (NJB) 234 235 Initial assignment of return value added to suppress compilation 236 warnings on some systems. 237 238 -CSPICE Version 1.0.0, 25-OCT-1997 (NJB) 239 240 Based on SPICELIB Version 1.2.0, 03-AUG-1994 (NJB) 241 242 -Index_Entries 243 244 equivalent strings 245 246 -& 247 */ 248 249 { /* Begin eqstr_c */ 250 251 /* 252 Local constants 253 */ 254 #define LBOUND ( (SpiceInt) 'a' ) 255 #define UBOUND ( (SpiceInt) 'z' ) 256 #define DELTA ( ( (SpiceInt) 'A' ) - LBOUND ) 257 258 259 /* 260 Local variables 261 */ 262 SpiceBoolean done; 263 SpiceBoolean retval; 264 265 ConstSpiceChar * pa; 266 ConstSpiceChar * pb; 267 268 SpiceInt ca; 269 SpiceInt cb; 270 271 SpiceInt lenA; 272 SpiceInt lenB; 273 274 275 /* 276 Initialize the return value retval in order to make certain 277 compilers happy. This initial value is not used later; retval 278 is set explicitly in each case below. 279 */ 280 retval = SPICEFALSE; 281 282 283 /* 284 Check the input string pointers to make sure they're non-null. 285 */ 286 CHKPTR_VAL ( CHK_DISCOVER, "eqstr_c", a, retval ); 287 CHKPTR_VAL ( CHK_DISCOVER, "eqstr_c", b, retval ); 288 289 290 /* 291 The general plan is to move a pair of pointers (PA, PB) 292 through strings A and B, skipping blank characters and 293 comparing others one-for-one. 294 295 Repeat: 296 297 If (A is blank) then 298 Increment A 299 300 Else if (B is blank) then 301 Increment B 302 303 Else 304 If (A and B are equivalent) then 305 Increment A and B 306 Else 307 Return FALSE 308 309 If (A and B are past end) then 310 Return TRUE 311 312 Else if (A or B is past end and other is non-blank) then 313 Return FALSE 314 315 Else if (A or B is past end and other is blank) then 316 Return TRUE 317 318 Note that no pointer gets incremented more than once on each 319 pass through the loop. 320 321 On the other hand, in many cases the strings will be exactly 322 equal. If so, why knock ourselves out? 323 */ 324 325 if ( !strcmp( a, b ) ) 326 { 327 return ( SPICETRUE ); 328 } 329 330 pa = a; 331 pb = b; 332 lenA = strlen(a); 333 lenB = strlen(b); 334 335 336 /* 337 The possibility of an input string being empty does not occur in 338 Fortran, but it does here. Handle these cases (the case where both 339 are empty was handled by the strcmp test above). 340 */ 341 342 if ( ( lenA == 0 ) && ( lenB > 0 ) ) 343 { 344 return ( SPICEFALSE ); 345 } 346 347 if ( ( lenB == 0 ) && ( lenA > 0 ) ) 348 { 349 return ( SPICEFALSE ); 350 } 351 352 353 /* 354 On with the normal path. 355 */ 356 357 done = SPICEFALSE; 358 359 360 while ( !done ) 361 { 362 363 /* 364 At this point, we're guaranteed that strings a and b have more 365 characters to examine, that is: 366 367 ( pa <= a+lenA-1 ) and ( pb <= b+lenB-1 ) 368 369 */ 370 371 372 if ( isspace( (unsigned char) *pa ) ) 373 { 374 pa++; 375 } 376 else if ( isspace( (unsigned char) *pb) ) 377 { 378 pb++; 379 } 380 else 381 { 382 383 ca = (SpiceInt)(*pa); 384 cb = (SpiceInt)(*pb); 385 386 if ( ( ca >= LBOUND ) && ( ca <= UBOUND ) ) 387 { 388 ca = ca + DELTA; 389 } 390 391 if ( ( cb >= LBOUND ) && ( cb <= UBOUND ) ) 392 { 393 cb = cb + DELTA; 394 } 395 396 if ( ca == cb ) 397 { 398 pa++; 399 pb++; 400 } 401 else 402 { 403 /* 404 We now know the strings don't match. 405 */ 406 retval = SPICEFALSE; 407 done = SPICETRUE; 408 } 409 } 410 411 if ( !done ) 412 { 413 /* 414 At this point, the strings still match and we've advanced 415 at least one of the pointers. 416 */ 417 418 419 if ( ( (SpiceInt)(pa-a) ) == lenA ) 420 { 421 /* 422 There are no more characters in string a to examine. The 423 rest of string b had better be white space, or else we had 424 better be at the end of string b. 425 */ 426 427 if ( ( (SpiceInt)(pb-b) ) == lenB ) 428 { 429 /* 430 We've seen all of string b. 431 */ 432 433 retval = SPICETRUE; 434 done = SPICETRUE; 435 } 436 else if ( iswhsp_c(pb) ) 437 { 438 retval = SPICETRUE; 439 done = SPICETRUE; 440 } 441 else 442 { 443 retval = SPICEFALSE; 444 done = SPICETRUE; 445 } 446 } 447 /* 448 End of "no more characters in string a" case. 449 */ 450 451 else if ( ( (SpiceInt)(pb-b) ) == lenB ) 452 { 453 /* 454 There are no more characters in string b to examine. The 455 rest of string a had better be white space. 456 */ 457 if ( iswhsp_c(pa) ) 458 { 459 retval = SPICETRUE; 460 done = SPICETRUE; 461 } 462 else 463 { 464 retval = SPICEFALSE; 465 done = SPICETRUE; 466 } 467 } 468 469 /* 470 End of "no more characters in string b" case. 471 */ 472 } 473 /* 474 At this point, we've handled the cases where at least one 475 string is out of characters. If such a case occurred, done 476 has been set to SPICETRUE. 477 */ 478 479 } 480 /* 481 End of while loop. retval has been set. 482 */ 483 484 return (retval); 485 486 487 } /* End eqstr_c */ 488