substitute the Nth occurrence of a substring within a string (in place); if N is 0, substitute all occurrences; returns the number of substitutions; maximum output length is BUFSZ (BUFSZ-1 chars + terminating '\0') */
| 554 | if N is 0, substitute all occurrences; returns the number of substitutions; |
| 555 | maximum output length is BUFSZ (BUFSZ-1 chars + terminating '\0') */ |
| 556 | int |
| 557 | strNsubst( |
| 558 | char *inoutbuf, /* current string, and result buffer */ |
| 559 | const char *orig, /* old substring; if "", insert in front of Nth char */ |
| 560 | const char *replacement, /* new substring; if "", delete old substring */ |
| 561 | int n) /* which occurrence to replace; 0 => all */ |
| 562 | { |
| 563 | char *bp, *op, workbuf[BUFSZ]; |
| 564 | const char *rp; |
| 565 | unsigned len = (unsigned) strlen(orig); |
| 566 | int ocount = 0, /* number of times 'orig' has been matched */ |
| 567 | rcount = 0; /* number of substitutions made */ |
| 568 | |
| 569 | for (bp = inoutbuf, op = workbuf; *bp && op < &workbuf[BUFSZ - 1]; ) { |
| 570 | if ((!len || !strncmp(bp, orig, len)) && (++ocount == n || n == 0)) { |
| 571 | /* Nth match found */ |
| 572 | for (rp = replacement; *rp && op < &workbuf[BUFSZ - 1]; ) |
| 573 | *op++ = *rp++; |
| 574 | ++rcount; |
| 575 | if (len) { |
| 576 | bp += len; /* skip 'orig' */ |
| 577 | continue; |
| 578 | } |
| 579 | } |
| 580 | /* no match (or len==0) so retain current character */ |
| 581 | *op++ = *bp++; |
| 582 | } |
| 583 | if (!len && n == ocount + 1) { |
| 584 | /* special case: orig=="" (!len) and n==strlen(inoutbuf)+1, |
| 585 | insert in front of terminator (in other words, append); |
| 586 | [when orig=="", ocount will have been incremented once for |
| 587 | each input char] */ |
| 588 | for (rp = replacement; *rp && op < &workbuf[BUFSZ - 1]; ) |
| 589 | *op++ = *rp++; |
| 590 | ++rcount; |
| 591 | } |
| 592 | if (rcount) { |
| 593 | *op = '\0'; |
| 594 | Strcpy(inoutbuf, workbuf); |
| 595 | } |
| 596 | return rcount; |
| 597 | } |
| 598 | |
| 599 | /* search for a word in a space-separated list; returns non-Null if found */ |
| 600 | const char * |
no outgoing calls
no test coverage detected