Ejemplo n.º 1
0
static void
test_container_smartlist_sort_ptrs(void *arg)
{
  (void)arg;
  int array[10];
  int *arrayptrs[11];
  smartlist_t *sl = smartlist_new();
  unsigned i=0, j;

  for (j = 0; j < ARRAY_LENGTH(array); ++j) {
    smartlist_add(sl, &array[j]);
    arrayptrs[i++] = &array[j];
    if (j == 5) {
      smartlist_add(sl, &array[j]);
      arrayptrs[i++] = &array[j];
    }
  }

  for (i = 0; i < 10; ++i) {
    smartlist_shuffle(sl);
    smartlist_sort_pointers(sl);
    for (j = 0; j < ARRAY_LENGTH(arrayptrs); ++j) {
      tt_ptr_op(smartlist_get(sl, j), ==, arrayptrs[j]);
    }
  }

 done:
  smartlist_free(sl);
}
Ejemplo n.º 2
0
/** Run unit tests for smartlist-of-strings functionality. */
static void
test_container_smartlist_strings(void)
{
  smartlist_t *sl = smartlist_new();
  char *cp=NULL, *cp_alloc=NULL;
  size_t sz;

  /* Test split and join */
  test_eq(0, smartlist_len(sl));
  smartlist_split_string(sl, "abc", ":", 0, 0);
  test_eq(1, smartlist_len(sl));
  test_streq("abc", smartlist_get(sl, 0));
  smartlist_split_string(sl, "a::bc::", "::", 0, 0);
  test_eq(4, smartlist_len(sl));
  test_streq("a", smartlist_get(sl, 1));
  test_streq("bc", smartlist_get(sl, 2));
  test_streq("", smartlist_get(sl, 3));
  cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
  test_streq(cp_alloc, "abcabc");
  tor_free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
  test_streq(cp_alloc, "abc!a!bc!");
  tor_free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  test_streq(cp_alloc, "abcXYaXYbcXY");
  tor_free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  test_streq(cp_alloc, "abcXYaXYbcXYXY");
  tor_free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
  test_streq(cp_alloc, "abcabc");
  tor_free(cp_alloc);

  smartlist_split_string(sl, "/def/  /ghijk", "/", 0, 0);
  test_eq(8, smartlist_len(sl));
  test_streq("", smartlist_get(sl, 4));
  test_streq("def", smartlist_get(sl, 5));
  test_streq("  ", smartlist_get(sl, 6));
  test_streq("ghijk", smartlist_get(sl, 7));
  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
  test_eq(3, smartlist_len(sl));
  test_streq("a", smartlist_get(sl,0));
  test_streq("bbd", smartlist_get(sl,1));
  test_streq("cdef", smartlist_get(sl,2));
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE, 0);
  test_eq(8, smartlist_len(sl));
  test_streq("z", smartlist_get(sl,3));
  test_streq("zhasd", smartlist_get(sl,4));
  test_streq("", smartlist_get(sl,5));
  test_streq("bnud", smartlist_get(sl,6));
  test_streq("", smartlist_get(sl,7));

  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, " ab\tc \td ef  ", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  test_eq(4, smartlist_len(sl));
  test_streq("ab", smartlist_get(sl,0));
  test_streq("c", smartlist_get(sl,1));
  test_streq("d", smartlist_get(sl,2));
  test_streq("ef", smartlist_get(sl,3));
  smartlist_split_string(sl, "ghi\tj", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  test_eq(6, smartlist_len(sl));
  test_streq("ghi", smartlist_get(sl,4));
  test_streq("j", smartlist_get(sl,5));

  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  test_streq(cp_alloc, "");
  tor_free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  test_streq(cp_alloc, "XY");
  tor_free(cp_alloc);

  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  test_eq(3, smartlist_len(sl));
  test_streq("z", smartlist_get(sl, 0));
  test_streq("zhasd", smartlist_get(sl, 1));
  test_streq("bnud", smartlist_get(sl, 2));
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
  test_eq(5, smartlist_len(sl));
  test_streq("z", smartlist_get(sl, 3));
  test_streq("zhasd <>  <> bnud<>", smartlist_get(sl, 4));
  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "abcd\n", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  test_eq(1, smartlist_len(sl));
  test_streq("abcd", smartlist_get(sl, 0));
  smartlist_split_string(sl, "efgh", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  test_eq(2, smartlist_len(sl));
  test_streq("efgh", smartlist_get(sl, 1));

  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  /* Test swapping, shuffling, and sorting. */
  smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
  test_eq(7, smartlist_len(sl));
  smartlist_sort(sl, compare_strs_);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  test_streq(cp_alloc,"and,arma,by,nickm,onion,router,the");
  tor_free(cp_alloc);
  smartlist_swap(sl, 1, 5);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  test_streq(cp_alloc,"and,router,by,nickm,onion,arma,the");
  tor_free(cp_alloc);
  smartlist_shuffle(sl);
  test_eq(7, smartlist_len(sl));
  test_assert(smartlist_contains_string(sl, "and"));
  test_assert(smartlist_contains_string(sl, "router"));
  test_assert(smartlist_contains_string(sl, "by"));
  test_assert(smartlist_contains_string(sl, "nickm"));
  test_assert(smartlist_contains_string(sl, "onion"));
  test_assert(smartlist_contains_string(sl, "arma"));
  test_assert(smartlist_contains_string(sl, "the"));

  /* Test bsearch. */
  smartlist_sort(sl, compare_strs_);
  test_streq("nickm", smartlist_bsearch(sl, "zNicKM",
                                        compare_without_first_ch_));
  test_streq("and", smartlist_bsearch(sl, " AND", compare_without_first_ch_));
  test_eq_ptr(NULL, smartlist_bsearch(sl, " ANz", compare_without_first_ch_));

  /* Test bsearch_idx */
  {
    int f;
    smartlist_t *tmp = NULL;

    test_eq(0, smartlist_bsearch_idx(sl," aaa",compare_without_first_ch_,&f));
    test_eq(f, 0);
    test_eq(0, smartlist_bsearch_idx(sl," and",compare_without_first_ch_,&f));
    test_eq(f, 1);
    test_eq(1, smartlist_bsearch_idx(sl," arm",compare_without_first_ch_,&f));
    test_eq(f, 0);
    test_eq(1, smartlist_bsearch_idx(sl," arma",compare_without_first_ch_,&f));
    test_eq(f, 1);
    test_eq(2, smartlist_bsearch_idx(sl," armb",compare_without_first_ch_,&f));
    test_eq(f, 0);
    test_eq(7, smartlist_bsearch_idx(sl," zzzz",compare_without_first_ch_,&f));
    test_eq(f, 0);

    /* Test trivial cases for list of length 0 or 1 */
    tmp = smartlist_new();
    test_eq(0, smartlist_bsearch_idx(tmp, "foo",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 0);
    smartlist_insert(tmp, 0, (void *)("bar"));
    test_eq(1, smartlist_bsearch_idx(tmp, "foo",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 0);
    test_eq(0, smartlist_bsearch_idx(tmp, "aaa",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 0);
    test_eq(0, smartlist_bsearch_idx(tmp, "bar",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 1);
    /* ... and one for length 2 */
    smartlist_insert(tmp, 1, (void *)("foo"));
    test_eq(1, smartlist_bsearch_idx(tmp, "foo",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 1);
    test_eq(2, smartlist_bsearch_idx(tmp, "goo",
                                     compare_strs_for_bsearch_, &f));
    test_eq(f, 0);
    smartlist_free(tmp);
  }

  /* Test reverse() and pop_last() */
  smartlist_reverse(sl);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  test_streq(cp_alloc,"the,router,onion,nickm,by,arma,and");
  tor_free(cp_alloc);
  cp_alloc = smartlist_pop_last(sl);
  test_streq(cp_alloc, "and");
  tor_free(cp_alloc);
  test_eq(smartlist_len(sl), 6);
  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);
  cp_alloc = smartlist_pop_last(sl);
  test_eq_ptr(cp_alloc, NULL);

  /* Test uniq() */
  smartlist_split_string(sl,
                     "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
                     ",", 0, 0);
  smartlist_sort(sl, compare_strs_);
  smartlist_uniq(sl, compare_strs_, tor_free_);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  test_streq(cp_alloc, "50,a,canal,man,noon,panama,plan,radar");
  tor_free(cp_alloc);

  /* Test contains_string, contains_string_case and contains_int_as_string */
  test_assert(smartlist_contains_string(sl, "noon"));
  test_assert(!smartlist_contains_string(sl, "noonoon"));
  test_assert(smartlist_contains_string_case(sl, "nOOn"));
  test_assert(!smartlist_contains_string_case(sl, "nooNooN"));
  test_assert(smartlist_contains_int_as_string(sl, 50));
  test_assert(!smartlist_contains_int_as_string(sl, 60));

  /* Test smartlist_choose */
  {
    int i;
    int allsame = 1;
    int allin = 1;
    void *first = smartlist_choose(sl);
    test_assert(smartlist_contains(sl, first));
    for (i = 0; i < 100; ++i) {
      void *second = smartlist_choose(sl);
      if (second != first)
        allsame = 0;
      if (!smartlist_contains(sl, second))
        allin = 0;
    }
    test_assert(!allsame);
    test_assert(allin);
  }
  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_clear(sl);

  /* Test string_remove and remove and join_strings2 */
  smartlist_split_string(sl,
                    "Some say the Earth will end in ice and some in fire",
                    " ", 0, 0);
  cp = smartlist_get(sl, 4);
  test_streq(cp, "will");
  smartlist_add(sl, cp);
  smartlist_remove(sl, cp);
  tor_free(cp);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  test_streq(cp_alloc, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
  tor_free(cp_alloc);
  smartlist_string_remove(sl, "in");
  cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
  test_streq(cp_alloc, "Some+say+the+Earth+fire+end+some+ice+and");
  test_eq((int)sz, 40);

 done:

  SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  smartlist_free(sl);
  tor_free(cp_alloc);
}
/** Run unit tests for smartlist-of-strings functionality. */
static void
test_container_smartlist_strings(void *unused)
{
  smartlist_t *sl = smartlist_create();
  char *cp=NULL, *cp_alloc=NULL;
  size_t sz;

  /* Test split and join */
  tt_int_op(smartlist_len(sl), ==, 0);
  smartlist_split_string(sl, "abc", ":", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 1);
  tt_str_op(smartlist_get(sl, 0), ==, "abc");
  smartlist_split_string(sl, "a::bc::", "::", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 4);
  tt_str_op(smartlist_get(sl, 1), ==, "a");
  tt_str_op(smartlist_get(sl, 2), ==, "bc");
  tt_str_op(smartlist_get(sl, 3), ==, "");
  cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
  tt_str_op(cp_alloc, ==, "abcabc");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
  tt_str_op(cp_alloc, ==, "abc!a!bc!");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  tt_str_op(cp_alloc, ==, "abcXYaXYbcXY");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  tt_str_op(cp_alloc, ==, "abcXYaXYbcXYXY");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
  tt_str_op(cp_alloc, ==, "abcabc");
  free(cp_alloc);

  smartlist_split_string(sl, "/def/  /ghijk", "/", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 8);
  tt_str_op(smartlist_get(sl, 4), ==, "");
  tt_str_op(smartlist_get(sl, 5), ==, "def");
  tt_str_op(smartlist_get(sl, 6), ==, "  ");
  tt_str_op(smartlist_get(sl, 7), ==, "ghijk");
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
  tt_int_op(smartlist_len(sl), ==, 3);
  tt_str_op(smartlist_get(sl,0), ==, "a");
  tt_str_op(smartlist_get(sl,1), ==, "bbd");
  tt_str_op(smartlist_get(sl,2), ==, "cdef");
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE, 0);
  tt_int_op(smartlist_len(sl), ==, 8);
  tt_str_op(smartlist_get(sl,3), ==, "z");
  tt_str_op(smartlist_get(sl,4), ==, "zhasd");
  tt_str_op(smartlist_get(sl,5), ==, "");
  tt_str_op(smartlist_get(sl,6), ==, "bnud");
  tt_str_op(smartlist_get(sl,7), ==, "");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, " ab\tc \td ef  ", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 4);
  tt_str_op(smartlist_get(sl,0), ==, "ab");
  tt_str_op(smartlist_get(sl,1), ==, "c");
  tt_str_op(smartlist_get(sl,2), ==, "d");
  tt_str_op(smartlist_get(sl,3), ==, "ef");
  smartlist_split_string(sl, "ghi\tj", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 6);
  tt_str_op(smartlist_get(sl,4), ==, "ghi");
  tt_str_op(smartlist_get(sl,5), ==, "j");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  tt_str_op(cp_alloc, ==, "");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  tt_str_op(cp_alloc, ==, "XY");
  free(cp_alloc);

  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 3);
  tt_str_op(smartlist_get(sl, 0), ==, "z");
  tt_str_op(smartlist_get(sl, 1), ==, "zhasd");
  tt_str_op(smartlist_get(sl, 2), ==, "bnud");
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
  tt_int_op(smartlist_len(sl), ==, 5);
  tt_str_op(smartlist_get(sl, 3), ==, "z");
  tt_str_op(smartlist_get(sl, 4), ==, "zhasd <>  <> bnud<>");
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "abcd\n", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 1);
  tt_str_op(smartlist_get(sl, 0), ==, "abcd");
  smartlist_split_string(sl, "efgh", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 2);
  tt_str_op(smartlist_get(sl, 1), ==, "efgh");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  /* Test swapping, shuffling, and sorting. */
  smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 7);
  smartlist_sort(sl, _compare_strs);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "and,arma,by,nickm,onion,router,the");
  free(cp_alloc);
  smartlist_swap(sl, 1, 5);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "and,router,by,nickm,onion,arma,the");
  free(cp_alloc);
  smartlist_shuffle(sl);
  tt_int_op(smartlist_len(sl), ==, 7);
  tt_assert(smartlist_string_isin(sl, "and"));
  tt_assert(smartlist_string_isin(sl, "router"));
  tt_assert(smartlist_string_isin(sl, "by"));
  tt_assert(smartlist_string_isin(sl, "nickm"));
  tt_assert(smartlist_string_isin(sl, "onion"));
  tt_assert(smartlist_string_isin(sl, "arma"));
  tt_assert(smartlist_string_isin(sl, "the"));

  /* Test bsearch. */
  smartlist_sort(sl, _compare_strs);
  tt_str_op(smartlist_bsearch(sl, "zNicKM",
                              _compare_without_first_ch), ==, "nickm");
  tt_str_op(smartlist_bsearch(sl, " AND", _compare_without_first_ch), ==, "and");
  tt_ptr_op(smartlist_bsearch(sl, " ANz", _compare_without_first_ch), ==, NULL);

  /* Test bsearch_idx */
  {
    int f;
    tt_int_op(smartlist_bsearch_idx(sl," aaa",_compare_without_first_ch,&f),
              ==, 0);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," and",_compare_without_first_ch,&f),
              ==, 0);
    tt_int_op(f, ==, 1);
    tt_int_op(smartlist_bsearch_idx(sl," arm",_compare_without_first_ch,&f),
              ==, 1);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," arma",_compare_without_first_ch,&f),
              ==, 1);
    tt_int_op(f, ==, 1);
    tt_int_op(smartlist_bsearch_idx(sl," armb",_compare_without_first_ch,&f),
              ==, 2);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," zzzz",_compare_without_first_ch,&f),
              ==, 7);
    tt_int_op(f, ==, 0);
  }

  /* Test reverse() and pop_last() */
  smartlist_reverse(sl);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "the,router,onion,nickm,by,arma,and");
  free(cp_alloc);
  cp_alloc = smartlist_pop_last(sl);
  tt_str_op(cp_alloc, ==, "and");
  free(cp_alloc);
  tt_int_op(smartlist_len(sl), ==, 6);
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);
  cp_alloc = smartlist_pop_last(sl);
  tt_ptr_op(cp_alloc, ==, NULL);

  /* Test uniq() */
  smartlist_split_string(sl,
                     "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
                     ",", 0, 0);
  smartlist_sort(sl, _compare_strs);
  smartlist_uniq(sl, _compare_strs, free);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "50,a,canal,man,noon,panama,plan,radar");
  free(cp_alloc);

  /* Test string_isin and isin_case and num_isin */
  tt_assert(smartlist_string_isin(sl, "noon"));
  tt_assert(!smartlist_string_isin(sl, "noonoon"));
  tt_assert(smartlist_string_isin_case(sl, "nOOn"));
  tt_assert(!smartlist_string_isin_case(sl, "nooNooN"));
  tt_assert(smartlist_string_num_isin(sl, 50));
  tt_assert(!smartlist_string_num_isin(sl, 60));

  /* Test smartlist_choose */
  {
    int i;
    int allsame = 1;
    int allin = 1;
    void *first = smartlist_choose(sl);
    tt_assert(smartlist_isin(sl, first));
    for (i = 0; i < 100; ++i) {
      void *second = smartlist_choose(sl);
      if (second != first)
        allsame = 0;
      if (!smartlist_isin(sl, second))
        allin = 0;
    }
    tt_assert(!allsame);
    tt_assert(allin);
  }
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  /* Test string_remove and remove and join_strings2 */
  smartlist_split_string(sl,
                    "Some say the Earth will end in ice and some in fire",
                    " ", 0, 0);
  cp = smartlist_get(sl, 4);
  tt_str_op(cp, ==, "will");
  smartlist_add(sl, cp);
  smartlist_remove(sl, cp);
  free(cp);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
  free(cp_alloc);
  smartlist_string_remove(sl, "in");
  cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
  tt_str_op(cp_alloc, ==, "Some+say+the+Earth+fire+end+some+ice+and");
  tt_int_op((int)sz, ==, 40);

 end:

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_free(sl);
  free(cp_alloc);
}