codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
/* * Tiny String Library */ #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #if 0 # define __atomic_fetch_add __sync_fetch_and_add #elif 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 = (char *)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 false; 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; }
Private
[
?
]
Run code
Submit