Changeset 13 for trunk/src/helpers/xstring.c
- Timestamp:
- Nov 23, 2000, 7:36:41 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/xstring.c
r12 r13 51 51 * 3) If you need the char* pointer (e.g. for a call 52 52 * to another function), use XSTRING.psz. However, 53 * you should NEVER modify the psz pointer yourself 54 * because then these functions will get into trouble. 53 * you should ONLY modify the psz pointer yourself 54 * if the other XSTRING members are updated accordingly. 55 * You may, for example, change single characters 56 * in the psz buffer. By contrast, if you change the 57 * length of the string, you must update XSTRING.ulLength. 58 * Otherwise these functions will get into trouble. 55 59 * 56 60 * Also, you should never assume that the "psz" 57 61 * pointer has not changed after you have called 58 62 * one of the xstr* functions because these can 59 * always reallocate the buffer if needed. 63 * always reallocate the buffer if more memory 64 * was needed. 60 65 * 61 66 * 4) If (and only if) you have a char* buffer which … … 68 73 * The functions in this file used to be in stringh.c 69 74 * before V0.9.3 (2000-04-01). These have been largely 70 * rewritten with V0.9.6 (2000-11-01). 75 * rewritten with V0.9.6 (2000-11-01) and are now much 76 * more efficient. 71 77 * 72 78 * Note: Version numbering in this file relates to XWorkplace … … 145 151 * the XSTRING with. 146 152 * 153 * This does not create a copy of pszNew. Instead, 154 * pszNew is used as the member string in pxstr 155 * directly. 156 * 147 157 * Do not use this on an XSTRING which is already 148 158 * initialized. Use xstrset instead. 159 * 160 * Example: 161 * 162 + XSTRING str; 163 + xstrInitSet(&str, strdup("blah")); 149 164 * 150 165 *@@added V0.9.6 (2000-11-01) [umoeller] … … 173 188 * of an existing string. 174 189 * 190 * As opposed to xstrInitSet, this does create 191 * a copy of pcszSource. 192 * 175 193 * Do not use this on an XSTRING which is already 176 194 * initialized. Use xstrcpy instead. 195 * 196 * Example: 197 * 198 + XSTRING str; 199 + xstrInitCopy(&str, "blah"); 177 200 * 178 201 *@@added V0.9.6 (2000-11-01) [umoeller] … … 301 324 + xstrInit(&str, 0); 302 325 + xstrcpy(&str, "blah"); 326 * 327 * This sequence can be abbreviated using xstrInitCopy. 303 328 * 304 329 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxcpy … … 351 376 /* 352 377 *@@ xstrcat: 353 * appends pcszSource to pxstr, for which memory is allocated354 * asnecessary.378 * appends pcszSource to pxstr, for which memory is 379 * reallocated if necessary. 355 380 * 356 381 * If pxstr is empty, this behaves just like xstrcpy. … … 366 391 + xstrcat(&str, "blup"); 367 392 * 368 * would do the following: 369 * a) free the old value of str ("blah"); 370 * b) reallocate str; 371 * c) so that psz afterwards points to a new string containing 372 * "blahblup". 393 * After this, psz points to a new string containing 394 * "blahblup". 373 395 * 374 396 *@@changed V0.9.1 (99-12-20) [umoeller]: fixed memory leak … … 424 446 425 447 // 2) append source string: 426 strcpy(pxstr->psz + pxstr->ulLength, 427 pcszSource); 448 memcpy(pxstr->psz + pxstr->ulLength, 449 pcszSource, 450 ulSourceLength + 1); // null terminator 428 451 429 452 // in all cases, set new length 430 453 pxstr->ulLength += ulSourceLength; 431 454 ulrc = ulSourceLength; 432 } 455 456 } // end if (ulSourceLength) 433 457 // else no source specified or source is empty: 434 458 // do nothing … … 439 463 440 464 /* 465 *@@ xstrFindWord: 466 * searches for pstrFind in pxstr, starting at ulOfs. 467 * However, this only finds pstrFind if it's a "word", 468 * i.e. surrounded by one of the characters in the 469 * pcszBeginChars and pcszEndChars array. 470 * 471 * This is similar to strhFindWord, but this uses 472 * strhmemfind for fast searching, and it doesn't 473 * have to calculate the string lengths because these 474 * already in XSTRING. 475 * 476 * Returns 0 if no "word" was found, or the offset 477 * of the "word" in pxstr if found. 478 * 479 *@@added V0.9.6 (2000-11-12) [umoeller] 480 */ 481 482 PSZ xstrFindWord(const XSTRING *pxstr, // in: buffer to search ("haystack") 483 ULONG ulOfs, // in: where to begin search (0 = start) 484 const XSTRING *pstrFind, // in: word to find ("needle") 485 size_t *pShiftTable, // in: shift table (see strhmemfind) 486 PBOOL pfRepeatFind, // in: repeat find? (see strhmemfind) 487 const char *pcszBeginChars, // suggestion: "\x0d\x0a ()/\\-,." 488 const char *pcszEndChars) // suggestion: "\x0d\x0a ()/\\-,.:;" 489 { 490 PSZ pReturn = 0; 491 ULONG ulFoundLen = pstrFind->ulLength; 492 493 if ((pxstr->ulLength) && (ulFoundLen)) 494 { 495 const char *p = pxstr->psz + ulOfs; 496 497 do // while p 498 { 499 // p = strstr(p, pstrFind->psz); 500 p = (PSZ)strhmemfind(p, // in: haystack 501 pxstr->ulLength - (p - pxstr->psz), 502 // remaining length of haystack 503 pstrFind->psz, 504 ulFoundLen, 505 pShiftTable, 506 pfRepeatFind); 507 if (p) 508 { 509 // string found: 510 // check if that's a word 511 512 if (strhIsWord(pxstr->psz, 513 p, 514 ulFoundLen, 515 pcszBeginChars, 516 pcszEndChars)) 517 { 518 // valid end char: 519 pReturn = (PSZ)p; 520 break; 521 } 522 523 p += ulFoundLen; 524 } 525 } while (p); 526 527 } 528 return (pReturn); 529 } 530 531 /* 441 532 *@@ xstrrpl: 442 * replaces pstrSearch with pstrReplace in pxstr. 533 * replaces the first occurence of pstrSearch with 534 * pstrReplace in pxstr. 443 535 * 444 536 * Starting with V0.9.6, this operates entirely on 445 537 * XSTRING's for speed because we then know the string 446 538 * lengths already and can use memcpy instead of strcpy. 447 * This new version should be magnitudes faster. 539 * This new version should be magnitudes faster, 540 * especially with large string bufffers. 448 541 * 449 542 * None of the pointers can be NULL, but if pstrReplace … … 454 547 * (and pxstr was therefore not changed). 455 548 * 456 * If the string was found and (pulAfterOfs != NULL), 457 * *pulAfterOfs will be set to the first character 458 * after the new replacement string. This allows you 459 * to call this func again with the same strings to 460 * have several occurences replaced. 461 * 462 * Only the first occurence is replaced. To replace 463 * all occurences in a buffer, repeat calling this 464 * function until it returns 0. 549 * This starts the search at *pulOffset. If 550 * (*pulOffset == 0), this starts from the beginning 551 * of pxstr. 552 * If the string was found, *pulOffset will be set to the 553 * first character after the new replacement string. This 554 * allows you to call this func again with the same strings 555 * to have several occurences replaced (see the example below). 465 556 * 466 557 * There are two wrappers around this function which … … 476 567 * 477 568 + XSTRING str; 478 + ULONG ul Pos= 0;569 + ULONG ulOffset = 0; 479 570 + xstrInit(&str, 0); 480 571 + xstrcpy(&str, "Test phrase 1. Test phrase 2."); 481 572 + while (xstrrpl(&str, 482 + ulPos,573 + &ulPos, // in/out: offset 483 574 + "Test", // search 484 + "Dummy", // replace 485 + &ulPos)) 575 + "Dummy") // replace 486 576 + ; 487 577 * … … 493 583 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxrpl 494 584 *@@changed V0.9.6 (2000-11-01) [umoeller]: rewritten 585 *@@changed V0.9.6 (2000-11-12) [umoeller]: now using strhmemfind 495 586 */ 496 587 497 588 ULONG xstrrpl(PXSTRING pxstr, // in/out: string 498 ULONG ulOfs, // in: where to begin search (0 = start) 589 PULONG pulOfs, // in: where to begin search (0 = start); 590 // out: ofs of first char after replacement string 499 591 const XSTRING *pstrSearch, // in: search string; cannot be NULL 500 592 const XSTRING *pstrReplace, // in: replacement string; cannot be NULL 501 PULONG pulAfterOfs) // out: offset where found (ptr can be NULL) 502 { 503 ULONG ulrc = 0; 593 size_t *pShiftTable, // in: shift table (see strhmemfind) 594 PBOOL pfRepeatFind) // in: repeat find? (see strhmemfind) 595 { 596 ULONG ulrc = 0; // default: not found 504 597 505 598 if ((pxstr) && (pstrSearch) && (pstrReplace)) … … 508 601 509 602 // can we search this? 510 if ( ( ulOfs < pxstr->ulLength)603 if ( (*pulOfs < pxstr->ulLength) 511 604 && (cSearchLen) 512 605 ) 513 606 { 514 607 // yes: 515 PSZ pFound = strstr(pxstr->psz + ulOfs, 516 pstrSearch->psz); 517 608 /* PSZ pFound = strstr(pxstr->psz + *pulOfs, 609 pstrSearch->psz); */ 610 PSZ pFound = (PSZ)strhmemfind(pxstr->psz + *pulOfs, // in: haystack 611 pxstr->ulLength - *pulOfs, 612 pstrSearch->psz, 613 cSearchLen, 614 pShiftTable, 615 pfRepeatFind); 518 616 if (pFound) 519 617 { … … 569 667 + 1); // null terminator 570 668 669 // replace old buffer with new one 571 670 free(pxstr->psz); 572 671 pxstr->psz = pszNew; … … 627 726 // return new length 628 727 ulrc = cbNeeded - 1; 629 if (pulAfterOfs) 630 *pulAfterOfs = ulFoundOfs + cReplaceLen; 631 } 632 } 633 } 728 *pulOfs = ulFoundOfs + cReplaceLen; 729 } // end if (pFound) 730 } // end if ( (*pulOfs < pxstr->ulLength) ... 731 } // end if ((pxstr) && (pstrSearch) && (pstrReplace)) 634 732 635 733 return (ulrc); … … 638 736 /* 639 737 *@@ xstrcrpl: 640 * wrapper around xstrrpl which allows using C strings738 * wrapper around xstrrpl() which allows using C strings 641 739 * for the find and replace parameters. 642 740 * 741 * This creates two temporary XSTRING's for pcszSearch 742 * pcszReplace. As a result, this is slower than xstrrpl. 743 * If you search with the same strings several times, 744 * you'll be better off using xstrrpl() directly. 745 * 643 746 *@@added V0.9.6 (2000-11-01) [umoeller] 644 747 */ 645 748 646 749 ULONG xstrcrpl(PXSTRING pxstr, // in/out: string 647 ULONG ulOfs, // in: where to begin search (0 = start) 750 PULONG pulOfs, // in: where to begin search (0 = start); 751 // out: ofs of first char after replacement string 648 752 const char *pcszSearch, // in: search string; cannot be NULL 649 const char *pcszReplace, // in: replacement string; cannot be NULL 650 PULONG pulAfterOfs) // out: offset where found (ptr can be NULL) 651 { 652 ULONG ulrc = 0; 753 const char *pcszReplace) // in: replacement string; cannot be NULL 754 { 755 // ULONG ulrc = 0; 653 756 XSTRING xstrFind, 654 757 xstrReplace; 655 xstrInit(&xstrFind, 0); 656 xstrset(&xstrFind, (PSZ)pcszSearch); 657 xstrInit(&xstrReplace, 0); 658 xstrset(&xstrReplace, (PSZ)pcszReplace); 659 660 return (xstrrpl(pxstr, ulOfs, &xstrFind, &xstrReplace, pulAfterOfs)); 758 size_t ShiftTable[256]; 759 BOOL fRepeat = FALSE; 760 // initialize find/replace strings... note that the 761 // C strings are not free()'able, so we MUST NOT use xstrClear 762 // before leaving 763 xstrInitSet(&xstrFind, (PSZ)pcszSearch); 764 xstrInitSet(&xstrReplace, (PSZ)pcszReplace); 765 766 return (xstrrpl(pxstr, pulOfs, &xstrFind, &xstrReplace, ShiftTable, &fRepeat)); 661 767 } 662 768
Note:
See TracChangeset
for help on using the changeset viewer.