<commit_before>#include "iwxstr.h"
#include "iwlog.h"

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <errno.h>

// Default IWXSTR initial size
#ifndef IWXSTR_AUNIT
#define IWXSTR_AUNIT 16
#endif

struct _IWXSTR {
  char  *ptr;     /**< Data buffer */
  size_t size;    /**< Actual data size */
  size_t asize;   /**< Allocated buffer size */
  void   (*user_data_free_fn)(void*);
  void  *user_data;
};

IWXSTR* iwxstr_new2(size_t siz) {
  if (!siz) {
    siz = IWXSTR_AUNIT;
  }
  IWXSTR *xstr = malloc(sizeof(*xstr));
  if (!xstr) {
    return 0;
  }
  xstr->ptr = malloc(siz);
  if (!xstr->ptr) {
    free(xstr);
    return 0;
  }
  xstr->user_data = 0;
  xstr->user_data_free_fn = 0;
  xstr->size = 0;
  xstr->asize = siz;
  xstr->ptr[0] = '\0';
  return xstr;
}

IWXSTR* iwxstr_new(void) {
  return iwxstr_new2(IWXSTR_AUNIT);
}

IWXSTR* iwxstr_wrap(char *buf, size_t size, size_t asize) {
  IWXSTR *xstr = malloc(sizeof(*xstr));
  if (!xstr) {
    return 0;
  }
  xstr->user_data = 0;
  xstr->user_data_free_fn = 0;
  xstr->size = size;
  xstr->asize = asize;
  xstr->ptr = buf;

  if (xstr->size >= asize) {
    if (iwxstr_cat(xstr, buf, size)) {
      free(xstr);
      return 0;
    }
  } else {
    xstr->ptr[size] = '\0';
  }
  return xstr;
}

void iwxstr_destroy(IWXSTR *xstr) {
  if (!xstr) {
    return;
  }
  if (xstr->user_data_free_fn) {
    xstr->user_data_free_fn(xstr->user_data);
  }
  free(xstr->ptr);
  free(xstr);
}

char* iwxstr_destroy_keep_ptr(IWXSTR *xstr) {<commit_msg>* iwxstr_wrap fixes<commit_after>#include "iwxstr.h"
#include "iwlog.h"

#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <errno.h>

// Default IWXSTR initial size
#ifndef IWXSTR_AUNIT
#define IWXSTR_AUNIT 16
#endif

struct _IWXSTR {
  char  *ptr;     /**< Data buffer */
  size_t size;    /**< Actual data size */
  size_t asize;   /**< Allocated buffer size */
  void   (*user_data_free_fn)(void*);
  void  *user_data;
};

IWXSTR* iwxstr_new2(size_t siz) {
  if (!siz) {
    siz = IWXSTR_AUNIT;
  }
  IWXSTR *xstr = malloc(sizeof(*xstr));
  if (!xstr) {
    return 0;
  }
  xstr->ptr = malloc(siz);
  if (!xstr->ptr) {
    free(xstr);
    return 0;
  }
  xstr->user_data = 0;
  xstr->user_data_free_fn = 0;
  xstr->size = 0;
  xstr->asize = siz;
  xstr->ptr[0] = '\0';
  return xstr;
}

IWXSTR* iwxstr_new(void) {
  return iwxstr_new2(IWXSTR_AUNIT);
}

IWXSTR* iwxstr_wrap(char *buf, size_t size, size_t asize) {
  IWXSTR *xstr = malloc(sizeof(*xstr));
  if (!xstr) {
    return 0;
  }
  xstr->user_data = 0;
  xstr->user_data_free_fn = 0;
  xstr->size = size;
  xstr->asize = asize;
  xstr->ptr = buf;

  if (size >= asize) {
    xstr->ptr = malloc(xstr->size + 1);
    if (!xstr->ptr) {
      free(xstr);
      return 0;
    }
    xstr->asize = size + 1;
    memcpy(xstr->ptr, buf, size);
  }
  xstr->ptr[size] = '\0';
  return xstr;
}

void iwxstr_destroy(IWXSTR *xstr) {
  if (!xstr) {
    return;
  }
  if (xstr->user_data_free_fn) {
    xstr->user_data_free_fn(xstr->user_data);
  }
  free(xstr->ptr);
  free(xstr);
}

char* iwxstr_destroy_keep_ptr(IWXSTR *xstr) {
{'fraction_non_alphanumeric': 0.1690989847715736, 'fraction_numerical': 0.010786802030456852, 'mean_word_length': 3.1323722149410225, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3580231', 'n_tokens_mistral': 1480, 'n_tokens_neox': 1441, 'n_words': 276}