/* crunch.h Copyright (c) 2007, Felix L. Winkelmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Send bugs, suggestions and ideas to: felix@call-with-current-continuation.org Felix L. Winkelmann Unter den Gleichen 1 37130 Gleichen Germany */ #ifndef CRUNCH_H #define CRUNCH_H #include #include #include #include #include #include #include #include #ifdef __x86_64__ # include # define crunch_u32 uint32_t # define crunch_s32 int32_t #else # define crunch_u32 unsigned long # define crunch_s32 long #endif #ifndef __cplusplus # error "crunched code can only be compiled in C++ mode" #endif #define crunch_inline inline #define crunch_primitive static inline #define crunch_local static #ifndef crunch_malloc crunch_local void *crunch_malloc(size_t sz) { void *p = malloc(sz); assert(p != NULL); return p; } #endif #ifndef crunch_malloc_ref crunch_local int *crunch_malloc_ref(int n) { int *r = (int *)crunch_malloc(sizeof(int)); *r = n; return r; } #endif #ifndef crunch_free # define crunch_free free #endif struct crunch_bool { bool f; template crunch_bool(T) { f = true; } crunch_bool() { f = false; } crunch_bool(const crunch_bool &x) { f = x.f; } }; template<> crunch_bool::crunch_bool(bool x) { f = x; } struct crunch_unspecified { template crunch_unspecified(T) {} crunch_unspecified() {} }; template struct crunch_buffer { int *ref, size; T *ptr; typedef T eltype; void addref() { if(ref != 0) ++(*ref); } void release() { if(ref != 0) { if(--(*ref) == 0) { crunch_free(ref); crunch_free(ptr); #ifdef DBGALLOC printf("[releasing buffer %p]\n", ptr); #endif } } } crunch_buffer() { ref = 0; size = -1; ptr = NULL; } crunch_buffer(T *p) { ref = 0; size = -1; ptr = p; } virtual ~crunch_buffer() { release(); } crunch_buffer(const crunch_buffer &sp) { ref = sp.ref; addref(); size = sp.size; ptr = sp.ptr; } crunch_buffer &operator=(const crunch_buffer &sp) { if(ptr != sp.ptr) { release(); ref = sp.ref; addref(); size = sp.size; ptr = sp.ptr; } return *this; } int length() const { if(size == -1) { fprintf(stderr, "buffer length not available: %p\n", ptr); abort(); } return size; } int bytes() const { if(size == -1) { fprintf(stderr, "buffer size not available: %p\n", ptr); abort(); } return size * sizeof(T); } }; struct crunch_blob: public crunch_buffer { crunch_blob() { ref = crunch_malloc_ref(0); size = -1; ptr = NULL; } crunch_blob(const crunch_blob &sp) { ref = sp.ref; addref(); size = sp.size; ptr = sp.ptr; } crunch_blob(void *pptr, int bytes, int *pref) { ref = pref; addref(); size = bytes; ptr = pptr; } static crunch_blob fromcopy(void *pptr, int bytes) { crunch_blob v; v.ptr = crunch_malloc(bytes); memcpy(v.ptr, pptr, bytes); v.ref = crunch_malloc_ref(1); v.size = bytes; #ifdef DBGALLOC printf("[allocating blob %p of size %d]\n", v.ptr, bytes); #endif return v; } int length() const { if(size == -1) { fprintf(stderr, "blob length not available: %p\n", ptr); abort(); } return size; } int bytes() const { if(size == -1) { fprintf(stderr, "blob length not available: %p\n", ptr); abort(); } return size; } }; template struct crunch_vector: public crunch_buffer { crunch_vector() { this->ref = 0; this->size = -1; this->ptr = NULL; } crunch_vector(int n, T x) { this->ref = crunch_malloc_ref(1); this->size = n; this->ptr = (T *)crunch_malloc(sizeof(T) * n); assert(this->ptr != NULL); #ifdef DBGALLOC printf("[allocating buffer %p with %d elements of size %d]\n", this->ptr, n, sizeof(T)); #endif for(int i = 0; i < n; ++i) this->ptr[ i ] = x; } crunch_vector(T *p) { this->ref = 0; this->size = -1; this->ptr = p; } crunch_vector(const crunch_vector &sp) { this->ref = sp.ref; this->addref(); this->size = sp.size; this->ptr = sp.ptr; } crunch_vector(const crunch_blob &sp) { this->ref = sp.ref; this->addref(); this->size = sp.size; this->ptr = (T *)sp.ptr; } static crunch_vector fromcopy(void *pptr, int bytes) { crunch_vector v; v.ptr = (T *)crunch_malloc(bytes); memcpy(v.ptr, pptr, bytes); v.ref = crunch_malloc_ref(1); v.size = bytes / sizeof(T); #ifdef DBGALLOC printf("[allocating vector %p with %d elements of size %d]\n", v.ptr, v.size, sizeof(T)); #endif return v; } T &operator[](const int &i) const { return this->ptr[ i ]; } T &operator[](const int &i) { return this->ptr[ i ]; } void display(const char *p, const char *fstr) const { printf("#%s(", p); int n = this->length(); if(n > 0) { printf(fstr, this->ptr[ 0 ]); for(int i = 1; i < n; ++i) { putchar(' '); printf(fstr, this->ptr[ i ]); } } putchar(')'); } }; typedef crunch_vector crunch_u8vector; typedef crunch_vector crunch_s8vector; typedef crunch_vector crunch_u16vector; typedef crunch_vector crunch_s16vector; typedef crunch_vector crunch_u32vector; typedef crunch_vector crunch_s32vector; typedef crunch_vector crunch_f32vector; typedef crunch_vector crunch_f64vector; struct crunch_string: public crunch_vector { crunch_string() { ref = 0; size = -1; ptr = NULL; } crunch_string(char *p) { ref = 0; size = strlen(p); ptr = p; } crunch_string(int n, char x) { ref = crunch_malloc_ref(1); size = n; ptr = (char *)crunch_malloc(n); assert(ptr != NULL); #ifdef DBGALLOC printf("[allocating string %p with %d elements]\n", ptr, n); #endif memset(ptr, x, n); } crunch_string(const crunch_vector &sp) { ref = sp.ref; addref(); size = sp.size; ptr = sp.ptr; } crunch_string(const crunch_blob &sp) { ref = sp.ref; addref(); size = sp.size; ptr = (char *)sp.ptr; } operator void*() { char *ptr2 = strdup(ptr); #ifdef DBGALLOC printf("[duplicating string %p to %p]\n", ptr, ptr2); #endif return ptr2; } }; #define crunch__2a(x, y) ((x) * (y)) #define crunch__2b(x, y) ((x) + (y)) #define crunch__2d(x, y) ((x) - (y)) #define crunch__2f(x, y) ((x) / (y)) #define crunch_max(x, y) ((x) > (y) ? (x) : (y); } #define crunch_min(x, y) ((x) < (y) ? (x) : (y); } crunch_primitive int crunch_quotient(int x, int y) { return x / y; } crunch_primitive int crunch_remainder(int x, int y) { return x % y; } crunch_local int crunch_modulo(int x, int y) { double d = (double)x / (double)y; double i; if(modf(d, &i) == 0) return 0; else { double f = floor(d); double fx; modf(f, &fx); if(f == fx) return x - (int)f * y; else return x - (int)fx * y; } } crunch_primitive double exact_2d_3einexact(double x) { return x; } crunch_primitive double inexact_2d_3eexact(double x) { return (int)x; } template crunch_primitive double crunch_abs(N x) { return x < 0 ? -x : x; } template crunch_primitive bool crunch__3d(N1 x, N2 y) { return x == y; } template crunch_primitive bool crunch__3c(N1 x, N2 y) { return x < y; } template crunch_primitive bool crunch__3e(N1 x, N2 y) { return x > y; } template crunch_primitive bool crunch__3c_3d(N1 x, N2 y) { return x <= y; } template crunch_primitive bool crunch__3e_3d(N1 x, N2 y) { return x >= y; } template crunch_primitive bool crunch_eq_3f(T x, T y) { return x == y; } template crunch_primitive bool crunch_eqv_3f(T x, T y) { return x == y; } template crunch_primitive bool crunch_equal_3f(T x, T y) { return x == y; } template crunch_primitive bool crunch_equal_3f(crunch_buffer &x, crunch_buffer &y) { return x.ptr == y.ptr || (x.length() == y.length() && memcmp(x.ptr, y.ptr, x.bytes()) == 0); } template crunch_primitive bool crunch_eq_3f(T1 x, T2 y) { return false; } template crunch_primitive bool crunch_eqv_3f(T1 x, T2 y) { return false; } template crunch_primitive bool crunch_equal_3f(T1 x, T2 y) { return false; } crunch_primitive bool crunch_not(crunch_bool x) { return !x.f; } template crunch_primitive crunch_bool crunch_zero_3f(N x) { return x == 0; } template crunch_primitive crunch_bool crunch_positive_3f(N x) { return x > 0; } template crunch_primitive crunch_bool crunch_negative_3f(N x) { return x < 0; } template crunch_primitive crunch_bool crunch_integer_3f(N) { return false; } template<> crunch_inline crunch_bool crunch_integer_3f(int x) { return true; } template<> crunch_inline crunch_bool crunch_integer_3f(double x) { double i; return modf(x, &i) == 0; } crunch_primitive bool crunch_odd_3f(int x) { return (x & 0x02) != 0; } crunch_primitive bool crunch_even_3f(int x) { return !crunch_odd_3f(x); } crunch_primitive bool crunch_exact_3f(double) { return false; } crunch_primitive bool crunch_inexact_3f(int) { return true; } template crunch_primitive double crunch_sub1(N x) { return x - 1; } crunch_primitive int crunch_sub1(int x) { return x - 1; } crunch_primitive double crunch_add1(double x) { return x + 1; } crunch_primitive int crunch_add1(int x) { return x + 1; } crunch_primitive double crunch_sqrt(double x) { return sqrt(x); } crunch_primitive double crunch_sin(double x) { return sin(x); } crunch_primitive double crunch_cos(double x) { return cos(x); } crunch_primitive double crunch_tan(double x) { return tan(x); } crunch_primitive double crunch_exp(double x) { return exp(x); } crunch_primitive double crunch_log(double x) { return log(x); } crunch_primitive double crunch_expt(double x, double y) { return pow(x, y); } /* incorrect */ crunch_primitive double crunch_asin(double x) { return asin(x); } crunch_primitive double crunch_acos(double x) { return acos(x); } crunch_primitive double crunch_atan(double x) { return atan(x); } crunch_primitive double crunch_atan2(double x, double y) { return atan2(x, y); } crunch_primitive double crunch_floor(double x) { return floor(x); } crunch_primitive int crunch_floor(int x) { return x; } crunch_primitive double crunch_ceiling(double x) { return ceil(x); } crunch_primitive int crunch_ceiling(int x) { return x; } crunch_primitive double crunch_truncate(double x) { double n; modf(x, &n); return n; } crunch_primitive int crunch_truncate(int x) { return x; } crunch_local double crunch_round(double x) { double i, f, i2; if(x < 0.0) { f = modf(-x, &i); if(f < 0.5 || (f == 0.5 && modf(i * 0.5, &i2) == 0.0)) return -i; else return -(i + 1.0); } else if(x == 0.0/* || x == -0.0*/) return x; else { f = modf(x, &i); if(f < 0.5 || (f == 0.5 && modf(i * 0.5, &i2) == 0.0)) return i; else return i + 1.0; } } crunch_primitive int crunch_round(int x) { return x; } crunch_primitive crunch_unspecified crunch_void() { return 0; } crunch_primitive crunch_unspecified crunch_write_2dchar(char c) { putchar(c); return 0; } crunch_primitive crunch_unspecified crunch_newline() { putchar('\n'); return 0; } crunch_primitive crunch_unspecified crunch_flush_2doutput() { fflush(stdout); return 0; } crunch_primitive crunch_unspecified crunch_display(double n) { printf("%.15g", n); return 0; } crunch_primitive crunch_unspecified crunch_display(int n) { printf("%d", n); return 0; } crunch_primitive crunch_unspecified crunch_display(crunch_unspecified) { fputs("#", stdout); return 0; } crunch_primitive crunch_unspecified crunch_display(crunch_string &s) { if(s.size == -1) fputs(s.ptr, stdout); else printf("%.*s", s.size, s.ptr); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_blob &s) { printf("#", s.ptr); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_u8vector &s) { s.display("u8", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_s8vector &s) { s.display("s8", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_u16vector &s) { s.display("u16", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_s16vector &s) { s.display("s16", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_u32vector &s) { s.display("u32", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_s32vector &s) { s.display("s32", "%d"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_f32vector &s) { s.display("f32", "%g"); return 0; } crunch_primitive crunch_unspecified crunch_display(const crunch_f64vector &s) { s.display("f64", "%g"); return 0; } crunch_primitive crunch_u8vector crunch_make_2du8vector(int n, unsigned char x) { return crunch_u8vector(n, x); } crunch_primitive crunch_s8vector crunch_make_2ds8vector(int n, signed char x) { return crunch_s8vector(n, x); } crunch_primitive crunch_u16vector crunch_make_2du16vector(int n, unsigned short x) { return crunch_u16vector(n, x); } crunch_primitive crunch_s16vector crunch_make_2ds16vector(int n, short x) { return crunch_s16vector(n, x); } crunch_primitive crunch_u32vector crunch_make_2du32vector(int n, crunch_u32 x) { return crunch_u32vector(n, x); } crunch_primitive crunch_s32vector crunch_make_2ds32vector(int n, crunch_s32 x) { return crunch_s32vector(n, x); } crunch_primitive crunch_f32vector crunch_make_2df32vector(int n, float x) { return crunch_f32vector(n, x); } crunch_primitive crunch_f64vector crunch_make_2df64vector(int n, double x) { return crunch_f64vector(n, x); } crunch_primitive int crunch_u8vector_2dref(const crunch_u8vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_u8vector_2dset_21(crunch_u8vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive int crunch_u16vector_2dref(const crunch_u16vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_u16vector_2dset_21(crunch_u16vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive int crunch_u32vector_2dref(const crunch_u32vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_u32vector_2dset_21(crunch_u32vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive int crunch_s8vector_2dref(const crunch_s8vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_s8vector_2dset_21(crunch_s8vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive int crunch_s16vector_2dref(const crunch_s16vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_s16vector_2dset_21(crunch_s16vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive int crunch_s32vector_2dref(const crunch_s32vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_s32vector_2dset_21(crunch_s32vector &v, int i, int x) { v[ i ] = x; return 0; } crunch_primitive float crunch_f32vector_2dref(const crunch_f32vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_f32vector_2dset_21(crunch_f32vector &v, int i, float x) { v[ i ] = x; return 0; } crunch_primitive double crunch_f64vector_2dref(const crunch_f64vector &v, int i) { return v[ i ]; } crunch_primitive crunch_unspecified crunch_f64vector_2dset_21(crunch_f64vector &v, int i, double x) { v[ i ] = x; return 0; } crunch_primitive int crunch_u8vector_2dlength(const crunch_u8vector &s) { return s.length(); } crunch_primitive int crunch_s8vector_2dlength(const crunch_s8vector &s) { return s.length(); } crunch_primitive int crunch_u16vector_2dlength(const crunch_u16vector &s) { return s.length(); } crunch_primitive int crunch_s16vector_2dlength(const crunch_s16vector &s) { return s.length(); } crunch_primitive int crunch_u32vector_2dlength(const crunch_u32vector &s) { return s.length(); } crunch_primitive int crunch_s32vector_2dlength(const crunch_s32vector &s) { return s.length(); } crunch_primitive int crunch_f32vector_2dlength(const crunch_f32vector &s) { return s.length(); } crunch_primitive int crunch_f64vector_2dlength(const crunch_f64vector &s) { return s.length(); } crunch_primitive int crunch_bitwise_2dand(int x, int y) { return x & y; } crunch_primitive int crunch_bitwise_2dior(int x, int y) { return x | y; } crunch_primitive int crunch_bitwise_2dxor(int x, int y) { return x ^ y; } crunch_primitive int crunch_bitwise_2dnot(int x) { return ~x; } crunch_primitive int crunch_arithmetic_2dshift(int x, int s) { return s < 0 ? x >> -s : x << s; } crunch_primitive crunch_bool crunch_char_3d_3f(char x, char y) { return x == y; } crunch_primitive crunch_bool crunch_char_3e_3f(char x, char y) { return x > y; } crunch_primitive crunch_bool crunch_char_3c_3f(char x, char y) { return x < y; } crunch_primitive crunch_bool crunch_char_3e_3d_3f(char x, char y) { return x >= y; } crunch_primitive crunch_bool crunch_char_3c_3d_3f(char x, char y) { return x <= y; } crunch_primitive crunch_bool crunch_char_2dci_3d_3f(char x, char y) { return tolower(x) == tolower(y); } crunch_primitive crunch_bool crunch_char_2dci_3e_3f(char x, char y) { return tolower(x) > tolower(y); } crunch_primitive crunch_bool crunch_char_2dci_3c_3f(char x, char y) { return tolower(x) < tolower(y); } crunch_primitive crunch_bool crunch_char_2dci_3e_3d_3f(char x, char y) { return tolower(x) >= tolower(y); } crunch_primitive crunch_bool crunch_char_2dci_3c_3d_3f(char x, char y) { return tolower(x) <= tolower(y); } crunch_primitive int crunch_char_2d_3einteger(unsigned char c) { return c; } crunch_primitive unsigned char crunch_integer_2d_3echar(int n) { return n; } crunch_primitive crunch_string crunch_make_2dstring(int n, char c) { return crunch_string(n, c); } crunch_primitive unsigned char crunch_string_2dref(const crunch_string &s, int i) { return s[ i ]; } crunch_primitive crunch_unspecified crunch_string_2dset_21(crunch_string &s, int i, char c) { s[ i ] = c; return 0; } crunch_primitive int crunch_string_2dlength(const crunch_string &s) { return s.length(); } crunch_local bool crunch_string_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); return n1 == n2 && !memcmp(s1.ptr, s2.ptr, n1); } crunch_local bool crunch_string_3e_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1); return c > 0 || (c == 0 && n1 > n2); } crunch_local bool crunch_string_3c_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1); return c < 0 || (c == 0 && n1 < n2); } crunch_local bool crunch_string_3e_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2); return c >= 0 || (c == 0 && n1 >= n2); } crunch_local bool crunch_string_3c_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2); return c<= 0 || (c == 0 && n1 <= n2); } crunch_local int crunch_memcmp_i(const char *p1, const char *p2, int n) { int c; while(n--) { if((c = tolower(*(p1++)) - tolower(*(p2++))) < 0) return -1; else if(c > 0) return 1; } return 0; } crunch_local bool crunch_string_2dci_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); return n1 == n2 && !crunch_memcmp_i(s1.ptr, s2.ptr, n1); } crunch_local bool crunch_string_2dci_3e_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1); return c > 0 || (c == 0 && n1 > n2); } crunch_local bool crunch_string_2dci_3c_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1); return c < 0 || (c == 0 && n1 < n2); } crunch_local bool crunch_string_2dci_3e_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2); return c >= 0 || (c == 0 && n1 >= n2); } crunch_local bool crunch_string_2dci_3c_3d_3f(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2); return c <= 0 || (c == 0 && n1 <= n2); } crunch_local crunch_unspecified crunch_error(const crunch_string &msg) { fputs("Error: ", stderr); fputs(msg.ptr, stderr); fputc('\n', stderr); exit(70); } crunch_primitive crunch_unspecified crunch_exit(int code) { exit(code); } crunch_primitive crunch_string crunch_blob_2d_3estring(const crunch_blob &b) { return crunch_string::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_string crunch_blob_2d_3estring_2fshared(crunch_blob &b) { return crunch_string(b); } crunch_primitive crunch_blob crunch_string_2d_3eblob(const crunch_string &b) { return crunch_blob::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_blob crunch_string_2d_3eblob_2fshared(crunch_string &b) { return crunch_blob(b.ptr, b.size, b.ref); } crunch_primitive crunch_u8vector crunch_blob_2d_3eu8vector(const crunch_blob &b) { return crunch_u8vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_u8vector crunch_blob_2d_3eu8vector_2fshared(crunch_blob &b) { return crunch_u8vector(b); } crunch_primitive crunch_blob crunch_u8vector_2d_3eblob(const crunch_u8vector &b) { return crunch_blob::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_blob crunch_u8vector_2d_3eblob_2fshared(crunch_u8vector &b) { return crunch_blob(b.ptr, b.size, b.ref); } crunch_primitive crunch_s8vector crunch_blob_2d_3es8vector(const crunch_blob &b) { return crunch_s8vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_s8vector crunch_blob_2d_3es8vector_2fshared(crunch_blob &b) { return crunch_s8vector(b); } crunch_primitive crunch_blob crunch_s8vector_2d_3eblob(const crunch_s8vector &b) { return crunch_blob::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_blob crunch_s8vector_2d_3eblob_2fshared(crunch_s8vector &b) { return crunch_blob(b.ptr, b.size, b.ref); } crunch_primitive crunch_u16vector crunch_blob_2d_3eu16vector(const crunch_blob &b) { return crunch_u16vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_u16vector crunch_blob_2d_3eu16vector_2fshared(crunch_blob &b) { return crunch_u16vector(b); } crunch_primitive crunch_blob crunch_u16vector_2d_3eblob(const crunch_u16vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 2); } crunch_primitive crunch_blob crunch_u16vector_2d_3eblob_2fshared(crunch_u16vector &b) { return crunch_blob(b.ptr, b.size * 2, b.ref); } crunch_primitive crunch_s16vector crunch_blob_2d_3es16vector(const crunch_blob &b) { return crunch_s16vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_s16vector crunch_blob_2d_3es16vector_2fshared(crunch_blob &b) { return crunch_s16vector(b); } crunch_primitive crunch_blob crunch_s16vector_2d_3eblob(const crunch_s16vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 2); } crunch_primitive crunch_blob crunch_s16vector_2d_3eblob_2fshared(crunch_s16vector &b) { return crunch_blob(b.ptr, b.size * 2, b.ref); } crunch_primitive crunch_u32vector crunch_blob_2d_3eu32vector(const crunch_blob &b) { return crunch_u32vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_u32vector crunch_blob_2d_3eu32vector_2fshared(crunch_blob &b) { return crunch_u32vector(b); } crunch_primitive crunch_blob crunch_u32vector_2d_3eblob(const crunch_u32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); } crunch_primitive crunch_blob crunch_u32vector_2d_3eblob_2fshared(crunch_u32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); } crunch_primitive crunch_s32vector crunch_blob_2d_3es32vector(const crunch_blob &b) { return crunch_s32vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_s32vector crunch_blob_2d_3es32vector_2fshared(crunch_blob &b) { return crunch_s32vector(b); } crunch_primitive crunch_blob crunch_s32vector_2d_3eblob(const crunch_s32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); } crunch_primitive crunch_blob crunch_s32vector_2d_3eblob_2fshared(crunch_s32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); } crunch_primitive crunch_f32vector crunch_blob_2d_3ef32vector(const crunch_blob &b) { return crunch_f32vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_f32vector crunch_blob_2d_3ef32vector_2fshared(crunch_blob &b) { return crunch_f32vector(b); } crunch_primitive crunch_blob crunch_f32vector_2d_3eblob(const crunch_f32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); } crunch_primitive crunch_blob crunch_f32vector_2d_3eblob_2fshared(crunch_f32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); } crunch_primitive crunch_f64vector crunch_blob_2d_3ef64vector(const crunch_blob &b) { return crunch_f64vector::fromcopy(b.ptr, b.length()); } crunch_primitive crunch_f64vector crunch_blob_2d_3ef64vector_2fshared(crunch_blob &b) { return crunch_f64vector(b); } crunch_primitive crunch_blob crunch_f64vector_2d_3eblob(const crunch_f64vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 8); } crunch_primitive crunch_blob crunch_f64vector_2d_3eblob_2fshared(crunch_f64vector &b) { return crunch_blob(b.ptr, b.size * 8, b.ref); } crunch_primitive crunch_string crunch_string_2dcopy(const crunch_string &b) { return crunch_string::fromcopy(b.ptr, b.length()); } crunch_local crunch_string crunch_substring(const crunch_string &s, int n, int m) { crunch_string str(m - n, '\0'); memcpy(str.ptr, s.ptr + n, m - n); return str; } crunch_local crunch_string crunch_string_2dappend(const crunch_string &s1, const crunch_string &s2) { int n1 = s1.length(), n2 = s2.length(); crunch_string str(n1 + n2, '\0'); memcpy(str.ptr, s1.ptr, n1); memcpy(str.ptr + n1, s2.ptr, n2); return str; } crunch_primitive crunch_unspecified crunch_string_2dfill_21(crunch_string &s, char c) { memset(s.ptr, c, s.length()); return 0; } crunch_local crunch_u8vector crunch_subu8vector(const crunch_u8vector &v, int n, int m) { crunch_u8vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, m - n); return str; } crunch_local crunch_s8vector crunch_subs8vector(const crunch_s8vector &v, int n, int m) { crunch_s8vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, m - n); return str; } crunch_local crunch_u16vector crunch_subu16vector(const crunch_u16vector &v, int n, int m) { crunch_u16vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 2); return str; } crunch_local crunch_s16vector crunch_subs16vector(const crunch_s16vector &v, int n, int m) { crunch_s16vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 2); return str; } crunch_local crunch_u32vector crunch_subu32vector(const crunch_u32vector &v, int n, int m) { crunch_u32vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 4); return str; } crunch_local crunch_s32vector crunch_subs32vector(const crunch_s32vector &v, int n, int m) { crunch_s32vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 4); return str; } crunch_local crunch_f32vector crunch_subf32vector(const crunch_f32vector &v, int n, int m) { crunch_f32vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 4); return str; } crunch_local crunch_f64vector crunch_subf64vector(const crunch_f64vector &v, int n, int m) { crunch_f64vector str(m - n, '\0'); memcpy(str.ptr, v.ptr + n, (m - n) * 8); return str; } #ifndef ___CHICKEN static int C_main_argc; static char **C_main_argv; #endif crunch_primitive int crunch_argc() { return C_main_argc; } crunch_primitive crunch_string crunch_argv_2dref(int n) { return C_main_argv[ n ]; } crunch_local crunch_string crunch_number_2d_3estring(int num, int radix) { char *buf = (char *)crunch_malloc(65); char *p; switch(radix) { case 2: buf[ 64 ] = '\0'; p = buf + 64; do { *(--p) = (num & 1) ? '1' : '0'; num /= 2; } while(num); return crunch_string::fromcopy(p, strlen(p)); case 8: sprintf(buf, "%o", num); return crunch_string::fromcopy(buf, strlen(buf)); case 16: sprintf(buf, "%x", num); return crunch_string::fromcopy(buf, strlen(buf)); default: sprintf(buf, "%d", num); return crunch_string::fromcopy(buf, strlen(buf)); } } crunch_local crunch_string crunch_number_2d_3estring(double num, int radix) { char *buf = (char *)crunch_malloc(65); sprintf(buf, "%g", num); return crunch_string::fromcopy(buf, strlen(buf)); } template crunch_local void crunch_string_2d_3enumber(const crunch_string &s, int radix, T &result) { char *ep; char buf[ 64 ]; int len = s.length(); memcpy(buf, s.ptr, len); buf[ len ] = '\0'; if(radix == 10) result = (T)strtod(buf, &ep); else result = strtol(buf, NULL, radix); } template<> void crunch_string_2d_3enumber(const crunch_string &s, int radix, int &result) { char *ep; char buf[ 64 ]; int len = s.length(); memcpy(buf, s.ptr, len); buf[ len ] = '\0'; result = strtol(s.ptr, &ep, radix); } crunch_primitive char crunch_char_2dupcase(char c) { return toupper(c); } crunch_primitive char crunch_char_2ddowncase(char c) { return tolower(c); } crunch_primitive bool crunch_char_2dwhitespace_3f(char c) { return isspace(c); } crunch_primitive bool crunch_char_2dalphabetic_3f(char c) { return isalpha(c); } crunch_primitive bool crunch_char_2dnumeric_3f(char c) { return isdigit(c); } crunch_primitive bool crunch_char_2dupper_2dcase_3f(char c) { return islower(c); } crunch_primitive bool crunch_char_2dlower_2dcase_3f(char c) { return isupper(c); } crunch_primitive int crunch_pointer_2du8_2dref(void *ptr, int i) { return ((unsigned char *)ptr)[ i ]; } crunch_primitive int crunch_pointer_2ds8_2dref(void *ptr, int i) { return ((char *)ptr)[ i ]; } crunch_primitive int crunch_pointer_2du16_2dref(void *ptr, int i) { return ((unsigned short *)ptr)[ i ]; } crunch_primitive int crunch_pointer_2ds16_2dref(void *ptr, int i) { return ((short *)ptr)[ i ]; } crunch_primitive unsigned int crunch_pointer_2du32_2dref(void *ptr, int i) { return ((unsigned int *)ptr)[ i ]; } crunch_primitive int crunch_pointer_2ds32_2dref(void *ptr, int i) { return ((int *)ptr)[ i ]; } crunch_primitive float crunch_pointer_2df32_2dref(void *ptr, int i) { return ((float *)ptr)[ i ]; } crunch_primitive double crunch_pointer_2df64_2dref(void *ptr, int i) { return ((double *)ptr)[ i ]; } crunch_primitive crunch_unspecified crunch_pointer_2du8_2dset_21(void *ptr, int i, int n) { ((unsigned char *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2ds8_2dset_21(void *ptr, int i, int n) { ((char *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2du16_2dset_21(void *ptr, int i, int n) { ((unsigned short *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2ds16_2dset_21(void *ptr, int i, int n) { ((short *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2du32_2dset_21(void *ptr, int i, int n) { ((unsigned int *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2ds32_2dset_21(void *ptr, int i, int n) { ((int *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2df32_2dset_21(void *ptr, int i, double n) { ((float *)ptr)[ i ] = n; return 0; } crunch_primitive crunch_unspecified crunch_pointer_2df64_2dset_21(void *ptr, int i, double n) { ((double *)ptr)[ i ] = n; return 0; } #endif