src/string.c

changeset 645
ec50abb285ad
parent 643
5700ba9154ab
child 657
3eeadf666d6b
equal deleted inserted replaced
644:fcaa0891ef28 645:ec50abb285ad
672 cx_strrepl_free_ibuf(firstbuf); 672 cx_strrepl_free_ibuf(firstbuf);
673 673
674 return result; 674 return result;
675 } 675 }
676 676
677 677 CxStrtokCtx cx_strtok(
678 cxstring str,
679 cxstring delim,
680 size_t limit
681 ) {
682 CxStrtokCtx ctx;
683 ctx.str = str;
684 ctx.delim = delim;
685 ctx.limit = limit;
686 ctx.pos = 0;
687 ctx.next_pos = 0;
688 ctx.delim_pos = 0;
689 ctx.found = 0;
690 ctx.delim_more = NULL;
691 ctx.delim_more_count = 0;
692 return ctx;
693 }
694
695 CxStrtokCtx cx_strtok_m(
696 cxmutstr str,
697 cxstring delim,
698 size_t limit
699 ) {
700 return cx_strtok(cx_strcast(str), delim, limit);
701 }
702
703 bool cx_strtok_next(
704 CxStrtokCtx *ctx,
705 cxstring *token
706 ) {
707 // abortion criteria
708 if (ctx->found >= ctx->limit || ctx->delim_pos >= ctx->str.length) {
709 return false;
710 }
711
712 // determine the search start
713 cxstring haystack = cx_strsubs(ctx->str, ctx->next_pos);
714
715 // search the next delimiter
716 cxstring delim = cx_strstr(haystack, ctx->delim);
717
718 // if found, make delim capture exactly the delimiter
719 if (delim.length > 0) {
720 delim.length = ctx->delim.length;
721 }
722
723 // if more delimiters are specified, check them now
724 if (ctx->delim_more_count > 0) {
725 cx_for_n(i, ctx->delim_more_count) {
726 cxstring d = cx_strstr(haystack, ctx->delim_more[i]);
727 if (d.length > 0 && (delim.length == 0 || d.ptr < delim.ptr)) {
728 delim.ptr = d.ptr;
729 delim.length = ctx->delim_more[i].length;
730 }
731 }
732 }
733
734 // store the token information and adjust the context
735 ctx->found++;
736 ctx->pos = ctx->next_pos;
737 token->ptr = &ctx->str.ptr[ctx->pos];
738 ctx->delim_pos = delim.length == 0 ?
739 ctx->str.length : (size_t) (delim.ptr - ctx->str.ptr);
740 token->length = ctx->delim_pos - ctx->pos;
741 ctx->next_pos = ctx->delim_pos + delim.length;
742
743 return true;
744 }
745
746 bool cx_strtok_next_m(
747 CxStrtokCtx *ctx,
748 cxmutstr *token
749 ) {
750 return cx_strtok_next(ctx, (cxstring *) token);
751 }
752
753 void cx_strtok_delim(
754 CxStrtokCtx *ctx,
755 cxstring const *delim,
756 size_t count
757 ) {
758 ctx->delim_more = delim;
759 ctx->delim_more_count = count;
760 }

mercurial