[ create a new paste ] login | about

Link: http://codepad.org/TRRgOvSo    [ raw code | output | fork ]

AaronMiller - C, pasted on Mar 16:
/*
 * Tiny String Library
 */
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#if 1
size_t __atomic_fetch_add(volatile size_t *x, size_t n) {
  size_t i;

  i = *x;
  *x += n;

  return i;
}
#endif

typedef union { void *p; size_t n; } ptradr_t;

struct string_s {
  int refcnt;
  size_t capacity, length;
  struct string_s *prev, *next;
  char *data;
};

typedef struct string_s *string_t;

struct string_s *g_str_head = (struct string_s *)0;
struct string_s *g_str_tail = (struct string_s *)0;

struct string_s *g_strar_head = (struct string_s *)0;
struct string_s *g_strar_tail = (struct string_s *)0;

void *memory(void *p, size_t n) {
  return !p&&n ? malloc(n) : p&&n ? realloc(p, n) : p&&!n ? (free(p), (void *)0) : (void *)0;
}

string_t newstring(const char *src) {
  string_t str;
  size_t l;

  src = src ? src : "";
  l = strlen(src) + 1;

  if (!(str = (string_t)memory((void *)0, sizeof(*str))))
    return (string_t)0;

  str->capacity = (l - l%64) + 64;

  if (!(str->data = (char *)memory((void *)0, str->capacity))) {
    memory((void *)str, 0);
    return (string_t)0;
  }

  str->refcnt = 1;
  str->length = l - 1;
  str->next = (struct string_s *)0;
  if ((str->prev = g_str_tail) != (struct string_s *)0)
    g_str_tail->next = str;
  else
    g_str_head = str;

  memcpy((void *)str->data, (const void *)src, l);

  return str;
}
string_t deletestring(string_t str) {
  if (!str)
    return (string_t)0;

  if (str->prev)
    str->prev->next = str->next;
  if (str->next)
    str->next->prev = str->prev;

  if (g_str_head==str)
    g_str_head = str->next;
  if (g_str_tail==str)
    g_str_tail = str->prev;

  if (g_strar_head==str)
    g_strar_head = str->next;
  if (g_strar_tail==str)
    g_strar_tail = str->prev;

  str->refcnt = 0;
  str->capacity = 0;
  str->length = 0;

  str->data = (char *)memory((void *)str->data, 0);
  return (string_t)memory((void *)str, 0);
}
void setstring(string_t dst, const char *src) {
  size_t l;

  if (!dst || !src)
    return;

  src = src ? src : "";
  l = strlen(src) + 1;

  if (l > dst->capacity) {
    dst->capacity = (l - l%64) + 64; /*round up to next boundary*/
    dst->data = memory((void *)dst->data, dst->capacity);
  }

  dst->length = l - 1;
  memcpy((void *)dst->data, (const void *)src, l);
}
size_t stringcapacity(string_t str) {
  return str ? str->capacity : 0;
}
size_t stringlength(string_t str) {
  return str ? str->length : 0;
}
void retainstring(string_t str) {
  if (!str)
    return;

  str->refcnt++;
}
string_t releasestring(string_t str) {
  if (str)
    if (--str->refcnt<=0)
      return deletestring(str);

  return (string_t)0;
}
char *stringdata(string_t str) {
  return str ? str->data : (char *)0;
}
const char *cstring(string_t str) {
  return str ? (const char *)str->data : "";
}
string_t copycstring(const char *cstr) {
  return newstring(cstr);
}
string_t copystring(string_t str) {
  return newstring(cstring(str));
}
bool appendcstring(string_t str, const char *cstr) {
  size_t l, n;

  if (!str)
    return newstring(cstr);

  if (!(l = strlen(cstr ? cstr : "")))
    return;

  if (str->length + l + 1 > str->capacity) {
    n = str->length + l + 1;

    str->capacity = (n - n%64) + 64;
    str->data = (char *)memory((void *)str->data, str->capacity);
    if (!str->data)
      return false;
  }

  memcpy(&str->data[str->length], (const void *)cstr, l + 1);
  str->length += l;

  return true;
}
bool appendstring(string_t dst, string_t src) {
  return appendcstring(dst, cstring(src));
}
string_t vformat(const char *f, va_list v) {
#define L 0x1000
#define N 128
  static char buf[L*N];
  static size_t i = 0;
  size_t I;

  I = __atomic_fetch_add(&i, 1) % N;

  vsnprintf(&buf[I*L], L-1, f, v);
  buf[I*L + L - 1] = 0;

  return newstring(&buf[I*L]);
#undef N
#undef L
}
string_t format(const char *f, ...) {
  string_t s;
  va_list v;

  va_start(v, f);
  s = vformat(f, v);
  va_end(v);

  return s;
}
const char *removestring(string_t str) {
  if (!str)
    return "";

  if (str->prev)
    str->prev->next = str->next;
  if (str->next)
    str->next->prev = str->prev;

  if (g_str_head==str)
    g_str_head = str->next;
  if (g_str_tail==str)
    g_str_tail = str->prev;

  str->next = (string_t)0;
  if ((str->prev = g_strar_tail) != (struct string_s *)0)
    g_strar_tail->next = str;
  else
    g_strar_head = str;
  g_strar_tail = str;

  str->refcnt = 0;
  return str->data ? (const char *)str->data : "";
}
void deleteremovedstrings() {
  string_t str, next;

  for(str=g_strar_head; str; str=next) {
    next = str->next;
    deletestring(str);
  }
}
void deleteallstrings() {
  deleteremovedstrings();

  while(g_str_head)
    deletestring(g_str_head);
}

int main() {
  string_t str;

  atexit(deleteallstrings);

  str = newstring("Hello, world!");
  printf("%s", removestring(format("%s\n", removestring(str))));

  return 0;
}


Output:
1
Hello, world!


Create a new paste based on this one


Comments: