Mercurial > hg > th-libs
comparison th_string.c @ 680:39c82d877251
Add new th_strelems_t structure for and join/split functions using them to
make certain operations nicer.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 04 Mar 2020 19:47:11 +0200 |
parents | 83a48de05fe9 |
children | d8738bfad0a8 |
comparison
equal
deleted
inserted
replaced
679:83a48de05fe9 | 680:39c82d877251 |
---|---|
554 | 554 |
555 return THERR_OK; | 555 return THERR_OK; |
556 } | 556 } |
557 | 557 |
558 | 558 |
559 int th_split_string(const th_char_t *str, th_char_t ***elems, size_t *nelems, const th_char_t *sep) | 559 int th_split_string_elems(const th_char_t *str, th_strelems_t *ctx, const th_char_t *sep) |
560 { | 560 { |
561 size_t start = 0, end; | 561 size_t start = 0, end; |
562 BOOL match = FALSE; | 562 BOOL match = FALSE; |
563 | 563 |
564 if (elems == NULL || nelems == NULL) | 564 if (str == NULL || ctx == NULL || sep == NULL) |
565 return THERR_NULLPTR; | 565 return THERR_NULLPTR; |
566 | 566 |
567 *elems = NULL; | 567 ctx->elems = NULL; |
568 *nelems = 0; | 568 ctx->nelems = 0; |
569 | 569 |
570 do | 570 do |
571 { | 571 { |
572 // Split foremost str element out | 572 // Split foremost str element out |
573 match = FALSE; | 573 match = FALSE; |
586 { | 586 { |
587 th_char_t *elem = th_strndup(str + start, end - start); | 587 th_char_t *elem = th_strndup(str + start, end - start); |
588 if (elem == NULL) | 588 if (elem == NULL) |
589 return THERR_MALLOC; | 589 return THERR_MALLOC; |
590 | 590 |
591 if ((*elems = th_realloc(*elems, sizeof(th_char_t **) * (*nelems + 1))) == NULL) | 591 if ((ctx->elems = th_realloc(ctx->elems, sizeof(th_char_t **) * (ctx->nelems + 1))) == NULL) |
592 return THERR_MALLOC; | 592 return THERR_MALLOC; |
593 | 593 |
594 (*elems)[*nelems] = elem; | 594 ctx->elems[ctx->nelems] = elem; |
595 (*nelems)++; | 595 ctx->nelems++; |
596 } | 596 } |
597 | 597 |
598 start = end + 1; | 598 start = end + 1; |
599 } while (match); | 599 } while (match); |
600 | 600 |
601 return THERR_OK; | 601 return THERR_OK; |
602 } | 602 } |
603 | 603 |
604 | 604 |
605 int th_join_string(th_char_t **str, th_char_t **elems, const size_t nelems, const th_char_t *sep) | 605 int th_split_string(const th_char_t *str, th_char_t ***elems, size_t *nelems, const th_char_t *sep) |
606 { | |
607 th_strelems_t ctx; | |
608 int res; | |
609 | |
610 if (elems == NULL || nelems == NULL) | |
611 return THERR_NULLPTR; | |
612 | |
613 if ((res = th_split_string_elems(str, &ctx, sep)) == THERR_OK) | |
614 return res; | |
615 | |
616 *elems = ctx.elems; | |
617 *nelems = ctx.nelems; | |
618 | |
619 return THERR_OK; | |
620 } | |
621 | |
622 | |
623 int th_join_string_elems(th_char_t **str, const th_strelems_t *ctx, const th_char_t *sep) | |
606 { | 624 { |
607 size_t len, n, offs, seplen, *elemlens; | 625 size_t len, n, offs, seplen, *elemlens; |
608 | 626 |
609 if (elems == NULL || str == NULL || sep == NULL) | 627 if (str == NULL || ctx == NULL || sep == NULL) |
610 return THERR_NULLPTR; | 628 return THERR_NULLPTR; |
611 | 629 |
612 if ((elemlens = th_malloc(nelems * sizeof(size_t))) == NULL) | 630 if ((elemlens = th_malloc(ctx->nelems * sizeof(size_t))) == NULL) |
613 return THERR_MALLOC; | 631 return THERR_MALLOC; |
614 | 632 |
615 seplen = th_strlen(sep); | 633 seplen = th_strlen(sep); |
616 | 634 |
617 for (len = n = 0; n < nelems; n++) | 635 for (len = n = 0; n < ctx->nelems; n++) |
618 { | 636 { |
619 len += elemlens[n] = th_strlen(ctx->elems[n]); | 637 len += elemlens[n] = th_strlen(ctx->elems[n]); |
620 } | 638 } |
621 | 639 |
622 len += 1 + n * seplen; | 640 len += 1 + n * seplen; |
625 { | 643 { |
626 th_free(elemlens); | 644 th_free(elemlens); |
627 return THERR_MALLOC; | 645 return THERR_MALLOC; |
628 } | 646 } |
629 | 647 |
630 for (offs = n = 0; n < nelems; n++) | 648 for (offs = n = 0; n < ctx->nelems; n++) |
631 { | 649 { |
632 if (n > 0) | 650 if (n > 0) |
633 { | 651 { |
634 memcpy((*str) + offs, sep, seplen * sizeof(th_char_t)); | 652 memcpy((*str) + offs, sep, seplen * sizeof(th_char_t)); |
635 offs += seplen; | 653 offs += seplen; |
636 } | 654 } |
637 | 655 |
638 memcpy((*str) + offs, elems[n], elemlens[n] * sizeof(th_char_t)); | 656 memcpy((*str) + offs, ctx->elems[n], elemlens[n] * sizeof(th_char_t)); |
639 offs += elemlens[n]; | 657 offs += elemlens[n]; |
640 } | 658 } |
641 | 659 |
642 (*str)[offs] = 0; | 660 (*str)[offs] = 0; |
643 | 661 |
644 return THERR_OK; | 662 return THERR_OK; |
663 } | |
664 | |
665 | |
666 int th_join_string(th_char_t **str, th_char_t **elems, const size_t nelems, const th_char_t *sep) | |
667 { | |
668 th_strelems_t ctx; | |
669 | |
670 ctx.elems = elems; | |
671 ctx.nelems = nelems; | |
672 | |
673 return th_join_string_elems(str, &ctx, sep); | |
674 } | |
675 | |
676 | |
677 void th_strelems_free(th_strelems_t *ctx) | |
678 { | |
679 if (ctx != NULL) | |
680 { | |
681 for (size_t n = 0; n < ctx->nelems; n++) | |
682 { | |
683 th_free(ctx->elems[n]); | |
684 } | |
685 | |
686 th_free(ctx->elems); | |
687 } | |
645 } | 688 } |
646 | 689 |
647 | 690 |
648 /* Find next non-whitespace character in string. | 691 /* Find next non-whitespace character in string. |
649 * Updates iPos into the position of such character and | 692 * Updates iPos into the position of such character and |