source: project/release/3/crunch/trunk/crunch.h @ 9918

Last change on this file since 9918 was 9918, checked in by Kon Lovett, 12 years ago

Using canonical directory structure.

File size: 31.4 KB
Line 
1/* crunch.h
2
3 Copyright (c) 2007, Felix L. Winkelmann
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
7 conditions are met:
8
9   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
10     disclaimer.
11   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
12     disclaimer in the documentation and/or other materials provided with the distribution.
13   Neither the name of the author nor the names of its contributors may be used to endorse or promote
14     products derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 POSSIBILITY OF SUCH DAMAGE.
25
26 Send bugs, suggestions and ideas to:
27
28 felix@call-with-current-continuation.org
29
30 Felix L. Winkelmann
31 Unter den Gleichen 1
32 37130 Gleichen
33 Germany
34
35*/
36
37
38#ifndef CRUNCH_H
39#define CRUNCH_H
40
41
42#include <stdio.h>
43#include <cmath>
44#include <cassert>
45#include <cstdlib>
46#include <cstring>
47#include <cctype>
48#include <cerrno>
49#include <climits>
50
51
52#ifdef __x86_64__
53# include <stdint.h>
54
55# define crunch_u32  uint32_t
56# define crunch_s32  int32_t
57#else
58# define crunch_u32  unsigned long
59# define crunch_s32  long
60#endif
61
62#ifndef __cplusplus
63# error "crunched code can only be compiled in C++ mode"
64#endif
65
66#define crunch_primitive    static inline
67#define crunch_local        static
68
69#ifdef CRUNCH_USE_ARENA
70
71#include <err.h>
72#include <arena/pool.h>
73#include <arena/proto.h>
74
75// libarena pool allocator; must be initialized in main()
76const struct arena_prototype *crunch_pool;
77
78#define crunch_malloc(sz)      crunch_pool->malloc(crunch_pool,sz,0)
79#define crunch_malloc_ref(n)   (int *)(crunch_pool->malloc(crunch_pool,sizeof(n),0))
80#define crunch_free
81
82#endif // CRUNCH_USE_ARENA
83
84#ifndef crunch_malloc
85crunch_local void *crunch_malloc(size_t sz) {
86  void *p = malloc(sz);
87  assert(p != NULL);
88  return p;
89}
90#endif
91
92#ifndef crunch_malloc_ref
93crunch_local int *crunch_malloc_ref(int n) {
94  int *r = (int *)crunch_malloc(sizeof(int));
95  *r = n;
96  return r;
97}
98#endif
99
100#ifndef crunch_free
101# define crunch_free free
102#endif
103
104struct crunch_bool {
105  bool f;
106  template<class T> crunch_bool(T) { f = true; }
107  crunch_bool() { f = false; }
108  crunch_bool(const crunch_bool &x) { f = x.f; }
109};
110
111template<> crunch_bool::crunch_bool(bool x) { f = x; }
112
113struct crunch_unspecified {
114  template<class T> crunch_unspecified(T) {}
115  crunch_unspecified() {}
116};
117
118template<class T> struct crunch_buffer {
119  int *ref, size;
120  T *ptr;
121
122  typedef T eltype;
123
124  void addref() { if(ref != 0) ++(*ref); }
125 
126  void release() {
127    if(ref != 0) {
128      if(--(*ref) == 0) {
129        crunch_free(ref);
130        crunch_free(ptr);
131#ifdef DBGALLOC
132        printf("[releasing buffer %p]\n", ptr);
133#endif
134      }
135    }
136  }
137
138  crunch_buffer() {
139    ref = 0;
140    size = -1;
141    ptr = NULL;
142  }
143
144  crunch_buffer(T *p) { 
145    ref = 0;
146    size = -1; 
147    ptr = p; 
148  }
149
150  virtual ~crunch_buffer() { release(); }
151
152  crunch_buffer(const crunch_buffer<T> &sp) {
153    ref = sp.ref;
154    addref();
155    size = sp.size;
156    ptr = sp.ptr;
157  }
158
159  crunch_buffer &operator=(const crunch_buffer<T> &sp) {
160    if(ptr != sp.ptr) {
161      release();
162      ref = sp.ref;
163      addref();
164      size = sp.size;
165      ptr = sp.ptr;
166    }
167
168    return *this;
169  }
170   
171  int length() const {
172    if(size == -1) {
173      fprintf(stderr, "buffer length not available: %p\n", ptr);
174      abort();
175    }
176   
177    return size;
178  }
179
180  int bytes() const {
181    if(size == -1) {
182      fprintf(stderr, "buffer size not available: %p\n", ptr);
183      abort();
184    }
185   
186    return size * sizeof(T);
187  }
188};
189
190struct crunch_blob: public crunch_buffer<void> {
191  crunch_blob() {
192    ref = crunch_malloc_ref(0);
193    size = -1;
194    ptr = NULL;
195  }
196
197  crunch_blob(const crunch_blob &sp) {
198    ref = sp.ref;
199    addref();
200    size = sp.size;
201    ptr = sp.ptr;
202  }
203
204  crunch_blob(void *pptr, int bytes, int *pref) {
205    ref = pref;
206    addref();
207    size = bytes;
208    ptr = pptr;
209  }
210
211  static crunch_blob fromcopy(void *pptr, int bytes) {
212    crunch_blob v;
213    v.ptr = crunch_malloc(bytes);
214    memcpy(v.ptr, pptr, bytes);
215    v.ref = crunch_malloc_ref(1);
216    v.size = bytes;
217#ifdef DBGALLOC
218    printf("[allocating blob %p of size %d]\n", v.ptr, bytes);
219#endif
220    return v;
221  }
222
223  int length() const {
224    if(size == -1) {
225      fprintf(stderr, "blob length not available: %p\n", ptr);
226      abort();
227    }
228   
229    return size;
230  }
231
232  int bytes() const {
233    if(size == -1) {
234      fprintf(stderr, "blob length not available: %p\n", ptr);
235      abort();
236    }
237   
238    return size;
239  }
240};
241
242template<class T> struct crunch_vector: public crunch_buffer<T> {
243  crunch_vector() {
244    this->ref = 0;
245    this->size = -1;
246    this->ptr = NULL;
247  }
248 
249  crunch_vector(int n, T x) {
250    this->ref = crunch_malloc_ref(1);
251    this->size = n;
252    this->ptr = (T *)crunch_malloc(sizeof(T) * n);
253    assert(this->ptr != NULL);
254#ifdef DBGALLOC
255    printf("[allocating buffer %p with %d elements of size %d]\n", this->ptr, n, sizeof(T));
256#endif
257   
258    for(int i = 0; i < n; ++i)
259      this->ptr[ i ] = x;
260  }
261
262  crunch_vector(T *p) { 
263    this->ref = 0;
264    this->size = -1; 
265    this->ptr = p; 
266  }
267
268  crunch_vector(const crunch_vector<T> &sp) {
269    this->ref = sp.ref;
270    this->addref();
271    this->size = sp.size;
272    this->ptr = sp.ptr;
273  }
274
275  crunch_vector(const crunch_blob &sp) {
276    this->ref = sp.ref;
277    this->addref();
278    this->size = sp.size;
279    this->ptr = (T *)sp.ptr;
280  }
281
282  static crunch_vector fromcopy(void *pptr, int bytes) {
283    crunch_vector<T> v;
284    v.ptr = (T *)crunch_malloc(bytes);
285    memcpy(v.ptr, pptr, bytes);
286    v.ref = crunch_malloc_ref(1);
287    v.size = bytes / sizeof(T);
288#ifdef DBGALLOC
289    printf("[allocating vector %p with %d elements of size %d]\n", v.ptr, v.size, sizeof(T));
290#endif
291    return v;
292  }
293
294  T &operator[](const int &i) const { return this->ptr[ i ]; }
295  T &operator[](const int &i) { return this->ptr[ i ]; }
296
297  void display(char *p, char *fstr) const {
298    printf("#%s(", p);
299    int n = this->length();
300
301    if(n > 0) {
302      printf(fstr, this->ptr[ 0 ]);
303
304      for(int i = 1; i < n; ++i) {
305        putchar(' ');
306        printf(fstr, this->ptr[ i ]);
307      }
308    }
309
310    putchar(')');
311  }
312};
313
314typedef crunch_vector<unsigned char> crunch_u8vector;
315typedef crunch_vector<signed char> crunch_s8vector;
316typedef crunch_vector<unsigned short> crunch_u16vector;
317typedef crunch_vector<short> crunch_s16vector;
318typedef crunch_vector<crunch_u32> crunch_u32vector;
319typedef crunch_vector<crunch_s32> crunch_s32vector;
320typedef crunch_vector<float> crunch_f32vector;
321typedef crunch_vector<double> crunch_f64vector;
322
323struct crunch_string: public crunch_vector<char> {
324  crunch_string() {
325    ref = 0;
326    size = -1;
327    ptr = NULL;
328  }
329
330  crunch_string(char *p) { 
331    ref = 0;
332    size = strlen(p); 
333    ptr = p; 
334  }
335 
336  crunch_string(int n, char x) {
337    ref = crunch_malloc_ref(1);
338    size = n;
339    ptr = (char *)crunch_malloc(n);
340    assert(ptr != NULL);
341#ifdef DBGALLOC
342    printf("[allocating string %p with %d elements]\n", ptr, n);
343#endif
344    memset(ptr, x, n);
345  }
346
347  crunch_string(const crunch_vector<char> &sp) {
348    ref = sp.ref;
349    addref();
350    size = sp.size;
351    ptr = sp.ptr;
352  }
353
354  crunch_string(const crunch_blob &sp) {
355    ref = sp.ref;
356    addref();
357    size = sp.size;
358    ptr = (char *)sp.ptr;
359  }
360
361  operator void*() { 
362    char *ptr2 = strdup(ptr);
363#ifdef DBGALLOC
364    printf("[duplicating string %p to %p]\n", ptr, ptr2);
365#endif
366    return ptr2;
367  }
368};
369
370#define crunch__2a(x, y)   ((x) * (y))
371#define crunch__2b(x, y)   ((x) + (y))
372#define crunch__2d(x, y)   ((x) - (y))
373#define crunch__2f(x, y)   ((x) / (y))
374#define crunch_max(x, y)   ((x) > (y) ? (x) : (y); }
375#define crunch_min(x, y)   ((x) < (y) ? (x) : (y); }
376
377crunch_primitive int crunch_quotient(int x, int y) { return x / y; }
378crunch_primitive int crunch_remainder(int x, int y) { return x % y; }
379
380crunch_local int crunch_modulo(int x, int y) {
381  double d = (double)x / (double)y;
382  double i;
383
384  if(modf(d, &i) == 0) return 0;
385  else {
386    double f = floor(d);
387    double fx;
388
389    modf(f, &fx);
390
391    if(f == fx) return x - (int)f * y;
392    else return x - (int)fx * y;
393  }
394}
395
396crunch_primitive double exact_2d_3einexact(double x) { return x; }
397crunch_primitive double inexact_2d_3eexact(double x) { return (int)x; }
398template<class N> crunch_primitive double crunch_abs(N x) { return x < 0 ? -x : x; }
399template<class N1, class N2> crunch_primitive bool crunch__3d(N1 x, N2 y) { return x == y; }
400template<class N1, class N2> crunch_primitive bool crunch__3c(N1 x, N2 y) { return x < y; }
401template<class N1, class N2> crunch_primitive bool crunch__3e(N1 x, N2 y) { return x > y; }
402template<class N1, class N2> crunch_primitive bool crunch__3c_3d(N1 x, N2 y) { return x <= y; }
403template<class N1, class N2> crunch_primitive bool crunch__3e_3d(N1 x, N2 y) { return x >= y; }
404template<class T> crunch_primitive bool crunch_eq_3f(T x, T y) { return x == y; }
405template<class T> crunch_primitive bool crunch_eqv_3f(T x, T y) { return x == y; }
406template<class T> crunch_primitive bool crunch_equal_3f(T x, T y) { return x == y; }
407
408template<class T> crunch_primitive bool crunch_equal_3f(crunch_buffer<T> &x, crunch_buffer<T> &y) { 
409  return x.ptr == y.ptr || (x.length() == y.length() && memcmp(x.ptr, y.ptr, x.bytes()) == 0);
410}
411
412template<class T1, class T2> crunch_primitive bool crunch_eq_3f(T1 x, T2 y) { return false; }
413template<class T1, class T2> crunch_primitive bool crunch_eqv_3f(T1 x, T2 y) { return false; }
414template<class T1, class T2> crunch_primitive bool crunch_equal_3f(T1 x, T2 y) { return false; }
415crunch_primitive bool crunch_not(crunch_bool x) { return !x.f; }
416template<class N> crunch_primitive crunch_bool crunch_zero_3f(N x) { return x == 0; }
417template<class N> crunch_primitive crunch_bool crunch_positive_3f(N x) { return x > 0; }
418template<class N> crunch_primitive crunch_bool crunch_negative_3f(N x) { return x < 0; }
419template<class N> crunch_primitive crunch_bool crunch_integer_3f(N) { return false; }
420template<> crunch_primitive crunch_bool crunch_integer_3f(int x) { return true; }
421template<> crunch_primitive crunch_bool crunch_integer_3f(double x) { double i; return modf(x, &i) == 0; }
422crunch_primitive bool crunch_odd_3f(int x) { return (x & 0x02) != 0; }
423crunch_primitive bool crunch_even_3f(int x) { return !crunch_odd_3f(x); }
424crunch_primitive bool crunch_exact_3f(double) { return false; }
425crunch_primitive bool crunch_inexact_3f(int) { return true; }
426template<class N> crunch_primitive double crunch_sub1(N x) { return x - 1; }
427crunch_primitive int crunch_sub1(int x) { return x - 1; }
428crunch_primitive double crunch_add1(double x) { return x + 1; }
429crunch_primitive int crunch_add1(int x) { return x + 1; }
430crunch_primitive double crunch_sqrt(double x) { return sqrt(x); }
431crunch_primitive double crunch_sin(double x) { return sin(x); }
432crunch_primitive double crunch_cos(double x) { return cos(x); }
433crunch_primitive double crunch_tan(double x) { return tan(x); }
434crunch_primitive double crunch_exp(double x) { return exp(x); }
435crunch_primitive double crunch_log(double x) { return log(x); }
436crunch_primitive double crunch_expt(double x, double y) { return pow(x, y); } /* incorrect */
437crunch_primitive double crunch_asin(double x) { return asin(x); }
438crunch_primitive double crunch_acos(double x) { return acos(x); }
439crunch_primitive double crunch_atan(double x) { return atan(x); }
440crunch_primitive double crunch_atan2(double x, double y) { return atan2(x, y); }
441crunch_primitive double crunch_floor(double x) { return floor(x); }
442crunch_primitive int crunch_floor(int x) { return x; }
443crunch_primitive double crunch_ceiling(double x) { return ceil(x); }
444crunch_primitive int crunch_ceiling(int x) { return x; }
445crunch_primitive double crunch_truncate(double x) { double n; modf(x, &n); return n; }
446crunch_primitive int crunch_truncate(int x) { return x; }
447
448crunch_local double crunch_round(double x) {
449  double i, f, i2;
450
451  if(x < 0.0) {
452    f = modf(-x, &i);
453    if(f < 0.5 || (f == 0.5 && modf(i * 0.5, &i2) == 0.0))
454      return -i;
455    else return -(i + 1.0);
456  }
457  else if(x == 0.0/* || x == -0.0*/)
458    return x;
459  else {
460    f = modf(x, &i);
461    if(f < 0.5 || (f == 0.5 && modf(i * 0.5, &i2) == 0.0))
462      return i;
463    else
464      return i + 1.0;
465  }
466}
467
468crunch_primitive int crunch_round(int x) { return x; }
469crunch_primitive crunch_unspecified crunch_void() { return 0; }
470crunch_primitive crunch_unspecified crunch_write_2dchar(char c) { putchar(c); return 0; }
471crunch_primitive crunch_unspecified crunch_newline() { putchar('\n'); return 0; }
472crunch_primitive crunch_unspecified crunch_flush_2doutput() { fflush(stdout); return 0; }
473crunch_primitive crunch_unspecified crunch_display(double n) { printf("%.15g", n); return 0; }
474crunch_primitive crunch_unspecified crunch_display(int n) { printf("%d", n); return 0; }
475crunch_primitive crunch_unspecified crunch_display(crunch_unspecified) { fputs("#<unprintable>", stdout); return 0; }
476
477crunch_primitive crunch_unspecified crunch_display(crunch_string &s) { 
478  if(s.size == -1) fputs(s.ptr, stdout);
479  else printf("%.*s", s.size, s.ptr); 
480
481  return 0;
482}
483
484crunch_primitive crunch_unspecified crunch_display(const crunch_blob &s) { printf("#<blob %p>", s.ptr); return 0; }
485crunch_primitive crunch_unspecified crunch_display(const crunch_u8vector &s) { s.display("u8", "%d"); return 0; }
486crunch_primitive crunch_unspecified crunch_display(const crunch_s8vector &s) { s.display("s8", "%d"); return 0; }
487crunch_primitive crunch_unspecified crunch_display(const crunch_u16vector &s) { s.display("u16", "%d"); return 0; }
488crunch_primitive crunch_unspecified crunch_display(const crunch_s16vector &s) { s.display("s16", "%d"); return 0; }
489crunch_primitive crunch_unspecified crunch_display(const crunch_u32vector &s) { s.display("u32", "%d"); return 0; }
490crunch_primitive crunch_unspecified crunch_display(const crunch_s32vector &s) { s.display("s32", "%d"); return 0; }
491crunch_primitive crunch_unspecified crunch_display(const crunch_f32vector &s) { s.display("f32", "%g"); return 0; }
492crunch_primitive crunch_unspecified crunch_display(const crunch_f64vector &s) { s.display("f64", "%g"); return 0; }
493crunch_primitive crunch_u8vector crunch_make_2du8vector(int n, unsigned char x) { return crunch_u8vector(n, x); }
494crunch_primitive crunch_s8vector crunch_make_2ds8vector(int n, signed char x) { return crunch_s8vector(n, x); }
495crunch_primitive crunch_u16vector crunch_make_2du16vector(int n, unsigned short x) { return crunch_u16vector(n, x); }
496crunch_primitive crunch_s16vector crunch_make_2ds16vector(int n, short x) { return crunch_s16vector(n, x); }
497crunch_primitive crunch_u32vector crunch_make_2du32vector(int n, crunch_u32 x) { return crunch_u32vector(n, x); }
498crunch_primitive crunch_s32vector crunch_make_2ds32vector(int n, crunch_s32 x) { return crunch_s32vector(n, x); }
499crunch_primitive crunch_f32vector crunch_make_2df32vector(int n, float x) { return crunch_f32vector(n, x); }
500crunch_primitive crunch_f64vector crunch_make_2df64vector(int n, double x) { return crunch_f64vector(n, x); }
501crunch_primitive int crunch_u8vector_2dref(const crunch_u8vector &v, int i) { return v[ i ]; }
502crunch_primitive crunch_unspecified crunch_u8vector_2dset_21(crunch_u8vector &v, int i, int x) { v[ i ] = x; return 0; }
503crunch_primitive int crunch_u16vector_2dref(const crunch_u16vector &v, int i) { return v[ i ]; }
504crunch_primitive crunch_unspecified crunch_u16vector_2dset_21(crunch_u16vector &v, int i, int x) { v[ i ] = x; return 0; }
505crunch_primitive int crunch_u32vector_2dref(const crunch_u32vector &v, int i) { return v[ i ]; }
506crunch_primitive crunch_unspecified crunch_u32vector_2dset_21(crunch_u32vector &v, int i, int x) { v[ i ] = x; return 0; }
507crunch_primitive int crunch_s8vector_2dref(const crunch_s8vector &v, int i) { return v[ i ]; }
508crunch_primitive crunch_unspecified crunch_s8vector_2dset_21(crunch_s8vector &v, int i, int x) { v[ i ] = x; return 0; }
509crunch_primitive int crunch_s16vector_2dref(const crunch_s16vector &v, int i) { return v[ i ]; }
510crunch_primitive crunch_unspecified crunch_s16vector_2dset_21(crunch_s16vector &v, int i, int x) { v[ i ] = x; return 0; }
511crunch_primitive int crunch_s32vector_2dref(const crunch_s32vector &v, int i) { return v[ i ]; }
512crunch_primitive crunch_unspecified crunch_s32vector_2dset_21(crunch_s32vector &v, int i, int x) { v[ i ] = x; return 0; }
513crunch_primitive float crunch_f32vector_2dref(const crunch_f32vector &v, int i) { return v[ i ]; }
514crunch_primitive crunch_unspecified crunch_f32vector_2dset_21(crunch_f32vector &v, int i, float x) { v[ i ] = x; return 0; }
515crunch_primitive double crunch_f64vector_2dref(const crunch_f64vector &v, int i) { return v[ i ]; }
516crunch_primitive crunch_unspecified crunch_f64vector_2dset_21(crunch_f64vector &v, int i, double x) { v[ i ] = x; return 0; }
517crunch_primitive int crunch_u8vector_2dlength(const crunch_u8vector &s) { return s.length(); }
518crunch_primitive int crunch_s8vector_2dlength(const crunch_s8vector &s) { return s.length(); }
519crunch_primitive int crunch_u16vector_2dlength(const crunch_u16vector &s) { return s.length(); }
520crunch_primitive int crunch_s16vector_2dlength(const crunch_s16vector &s) { return s.length(); }
521crunch_primitive int crunch_u32vector_2dlength(const crunch_u32vector &s) { return s.length(); }
522crunch_primitive int crunch_s32vector_2dlength(const crunch_s32vector &s) { return s.length(); }
523crunch_primitive int crunch_f32vector_2dlength(const crunch_f32vector &s) { return s.length(); }
524crunch_primitive int crunch_f64vector_2dlength(const crunch_f64vector &s) { return s.length(); }
525crunch_primitive int crunch_bitwise_2dand(int x, int y) { return x & y; }
526crunch_primitive int crunch_bitwise_2dior(int x, int y) { return x | y; }
527crunch_primitive int crunch_bitwise_2dxor(int x, int y) { return x ^ y; }
528crunch_primitive int crunch_bitwise_2dnot(int x) { return ~x; }
529crunch_primitive int crunch_arithmetic_2dshift(int x, int s) { return s < 0 ? x >> -s : x << s; }
530crunch_primitive crunch_bool crunch_char_3d_3f(char x, char y) { return x == y; }
531crunch_primitive crunch_bool crunch_char_3e_3f(char x, char y) { return x > y; }
532crunch_primitive crunch_bool crunch_char_3c_3f(char x, char y) { return x < y; }
533crunch_primitive crunch_bool crunch_char_3e_3d_3f(char x, char y) { return x >= y; }
534crunch_primitive crunch_bool crunch_char_3c_3d_3f(char x, char y) { return x <= y; }
535crunch_primitive crunch_bool crunch_char_2dci_3d_3f(char x, char y) { return tolower(x) == tolower(y); }
536crunch_primitive crunch_bool crunch_char_2dci_3e_3f(char x, char y) { return tolower(x) > tolower(y); }
537crunch_primitive crunch_bool crunch_char_2dci_3c_3f(char x, char y) { return tolower(x) < tolower(y); }
538crunch_primitive crunch_bool crunch_char_2dci_3e_3d_3f(char x, char y) { return tolower(x) >= tolower(y); }
539crunch_primitive crunch_bool crunch_char_2dci_3c_3d_3f(char x, char y) { return tolower(x) <= tolower(y); }
540crunch_primitive int crunch_char_2d_3einteger(unsigned char c) { return c; }
541crunch_primitive unsigned char crunch_integer_2d_3echar(int n) { return n; }
542crunch_primitive crunch_string crunch_make_2dstring(int n, char c) { return crunch_string(n, c); }
543crunch_primitive unsigned char crunch_string_2dref(const crunch_string &s, int i) { return s[ i ]; }
544crunch_primitive crunch_unspecified crunch_string_2dset_21(crunch_string &s, int i, char c) { s[ i ] = c; return 0; }
545crunch_primitive int crunch_string_2dlength(const crunch_string &s) { return s.length(); }
546
547crunch_local bool crunch_string_3d_3f(const crunch_string &s1, const crunch_string &s2) {
548  int n1 = s1.length(), n2 = s2.length();
549  return n1 == n2 && !memcmp(s1.ptr, s2.ptr, n1);
550}
551
552crunch_local bool crunch_string_3e_3f(const crunch_string &s1, const crunch_string &s2) {
553  int n1 = s1.length(), n2 = s2.length();
554  int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1);
555  return c > 0 || (c == 0 && n1 > n2);
556}
557
558crunch_local bool crunch_string_3c_3f(const crunch_string &s1, const crunch_string &s2) {
559  int n1 = s1.length(), n2 = s2.length();
560  int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1);
561  return c < 0 || (c == 0 && n1 < n2);
562}
563
564crunch_local bool crunch_string_3e_3d_3f(const crunch_string &s1, const crunch_string &s2) {
565  int n1 = s1.length(), n2 = s2.length();
566  int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2);
567  return c >= 0 || (c == 0 && n1 >= n2);
568}
569
570crunch_local bool crunch_string_3c_3d_3f(const crunch_string &s1, const crunch_string &s2) {
571  int n1 = s1.length(), n2 = s2.length();
572  int c = memcmp(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2);
573  return c<= 0 || (c == 0 && n1 <= n2);
574}
575
576crunch_local int crunch_memcmp_i(const char *p1, const char *p2, int n) {
577  int c;
578
579  while(n--) {
580    if((c = tolower(*(p1++)) - tolower(*(p2++))) < 0) return -1;
581    else if(c > 0) return 1;
582  }
583
584  return 0;
585}
586
587crunch_local bool crunch_string_2dci_3d_3f(const crunch_string &s1, const crunch_string &s2) {
588  int n1 = s1.length(), n2 = s2.length();
589  return n1 == n2 && !crunch_memcmp_i(s1.ptr, s2.ptr, n1);
590}
591
592crunch_local bool crunch_string_2dci_3e_3f(const crunch_string &s1, const crunch_string &s2) {
593  int n1 = s1.length(), n2 = s2.length();
594  int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1);
595  return c > 0 || (c == 0 && n1 > n2);
596}
597
598crunch_local bool crunch_string_2dci_3c_3f(const crunch_string &s1, const crunch_string &s2) {
599  int n1 = s1.length(), n2 = s2.length();
600  int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n1);
601  return c < 0 || (c == 0 && n1 < n2);
602}
603
604crunch_local bool crunch_string_2dci_3e_3d_3f(const crunch_string &s1, const crunch_string &s2) {
605  int n1 = s1.length(), n2 = s2.length();
606  int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2);
607  return c >= 0 || (c == 0 && n1 >= n2);
608}
609
610crunch_local bool crunch_string_2dci_3c_3d_3f(const crunch_string &s1, const crunch_string &s2) {
611  int n1 = s1.length(), n2 = s2.length();
612  int c = crunch_memcmp_i(s1.ptr, s2.ptr, n1 < n2 ? n1 : n2);
613  return c <= 0 || (c == 0 && n1 <= n2);
614}
615
616crunch_local crunch_unspecified crunch_error(const crunch_string &msg) { 
617  fputs("Error: ", stderr);
618  fputs(msg.ptr, stderr);
619  fputc('\n', stderr);
620  exit(70);
621}
622
623crunch_primitive crunch_unspecified crunch_exit(int code) { exit(code); }
624crunch_primitive crunch_string crunch_blob_2d_3estring(const crunch_blob &b) { return crunch_string::fromcopy(b.ptr, b.length()); }
625crunch_primitive crunch_string crunch_blob_2d_3estring_2fshared(crunch_blob &b) { return crunch_string(b); }
626crunch_primitive crunch_blob crunch_string_2d_3eblob(const crunch_string &b) { return crunch_blob::fromcopy(b.ptr, b.length()); }
627crunch_primitive crunch_blob crunch_string_2d_3eblob_2fshared(crunch_string &b) { return crunch_blob(b.ptr, b.size, b.ref); }
628crunch_primitive crunch_u8vector crunch_blob_2d_3eu8vector(const crunch_blob &b) { return crunch_u8vector::fromcopy(b.ptr, b.length()); }
629crunch_primitive crunch_u8vector crunch_blob_2d_3eu8vector_2fshared(crunch_blob &b) { return crunch_u8vector(b); }
630crunch_primitive crunch_blob crunch_u8vector_2d_3eblob(const crunch_u8vector &b) { return crunch_blob::fromcopy(b.ptr, b.length()); }
631crunch_primitive crunch_blob crunch_u8vector_2d_3eblob_2fshared(crunch_u8vector &b) { return crunch_blob(b.ptr, b.size, b.ref); }
632crunch_primitive crunch_s8vector crunch_blob_2d_3es8vector(const crunch_blob &b) { return crunch_s8vector::fromcopy(b.ptr, b.length()); }
633crunch_primitive crunch_s8vector crunch_blob_2d_3es8vector_2fshared(crunch_blob &b) { return crunch_s8vector(b); }
634crunch_primitive crunch_blob crunch_s8vector_2d_3eblob(const crunch_s8vector &b) { return crunch_blob::fromcopy(b.ptr, b.length()); }
635crunch_primitive crunch_blob crunch_s8vector_2d_3eblob_2fshared(crunch_s8vector &b) { return crunch_blob(b.ptr, b.size, b.ref); }
636crunch_primitive crunch_u16vector crunch_blob_2d_3eu16vector(const crunch_blob &b) { return crunch_u16vector::fromcopy(b.ptr, b.length()); }
637crunch_primitive crunch_u16vector crunch_blob_2d_3eu16vector_2fshared(crunch_blob &b) { return crunch_u16vector(b); }
638crunch_primitive crunch_blob crunch_u16vector_2d_3eblob(const crunch_u16vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 2); }
639crunch_primitive crunch_blob crunch_u16vector_2d_3eblob_2fshared(crunch_u16vector &b) { return crunch_blob(b.ptr, b.size * 2, b.ref); }
640crunch_primitive crunch_s16vector crunch_blob_2d_3es16vector(const crunch_blob &b) { return crunch_s16vector::fromcopy(b.ptr, b.length()); }
641crunch_primitive crunch_s16vector crunch_blob_2d_3es16vector_2fshared(crunch_blob &b) { return crunch_s16vector(b); }
642crunch_primitive crunch_blob crunch_s16vector_2d_3eblob(const crunch_s16vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 2); }
643crunch_primitive crunch_blob crunch_s16vector_2d_3eblob_2fshared(crunch_s16vector &b) { return crunch_blob(b.ptr, b.size * 2, b.ref); }
644crunch_primitive crunch_u32vector crunch_blob_2d_3eu32vector(const crunch_blob &b) { return crunch_u32vector::fromcopy(b.ptr, b.length()); }
645crunch_primitive crunch_u32vector crunch_blob_2d_3eu32vector_2fshared(crunch_blob &b) { return crunch_u32vector(b); }
646crunch_primitive crunch_blob crunch_u32vector_2d_3eblob(const crunch_u32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); }
647crunch_primitive crunch_blob crunch_u32vector_2d_3eblob_2fshared(crunch_u32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); }
648crunch_primitive crunch_s32vector crunch_blob_2d_3es32vector(const crunch_blob &b) { return crunch_s32vector::fromcopy(b.ptr, b.length()); }
649crunch_primitive crunch_s32vector crunch_blob_2d_3es32vector_2fshared(crunch_blob &b) { return crunch_s32vector(b); }
650crunch_primitive crunch_blob crunch_s32vector_2d_3eblob(const crunch_s32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); }
651crunch_primitive crunch_blob crunch_s32vector_2d_3eblob_2fshared(crunch_s32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); }
652crunch_primitive crunch_f32vector crunch_blob_2d_3ef32vector(const crunch_blob &b) { return crunch_f32vector::fromcopy(b.ptr, b.length()); }
653crunch_primitive crunch_f32vector crunch_blob_2d_3ef32vector_2fshared(crunch_blob &b) { return crunch_f32vector(b); }
654crunch_primitive crunch_blob crunch_f32vector_2d_3eblob(const crunch_f32vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 4); }
655crunch_primitive crunch_blob crunch_f32vector_2d_3eblob_2fshared(crunch_f32vector &b) { return crunch_blob(b.ptr, b.size * 4, b.ref); }
656crunch_primitive crunch_f64vector crunch_blob_2d_3ef64vector(const crunch_blob &b) { return crunch_f64vector::fromcopy(b.ptr, b.length()); }
657crunch_primitive crunch_f64vector crunch_blob_2d_3ef64vector_2fshared(crunch_blob &b) { return crunch_f64vector(b); }
658crunch_primitive crunch_blob crunch_f64vector_2d_3eblob(const crunch_f64vector &b) { return crunch_blob::fromcopy(b.ptr, b.length() * 8); }
659crunch_primitive crunch_blob crunch_f64vector_2d_3eblob_2fshared(crunch_f64vector &b) { return crunch_blob(b.ptr, b.size * 8, b.ref); }
660crunch_primitive crunch_string crunch_string_2dcopy(const crunch_string &b) { return crunch_string::fromcopy(b.ptr, b.length()); }
661
662crunch_local crunch_string crunch_substring(const crunch_string &s, int n, int m) { 
663  crunch_string str(m - n, '\0');
664  memcpy(str.ptr, s.ptr + n, m - n);
665  return str;
666}
667
668crunch_local crunch_string crunch_string_2dappend(const crunch_string &s1, const crunch_string &s2) {
669  int n1 = s1.length(), n2 = s2.length();
670  crunch_string str(n1 + n2, '\0');
671  memcpy(str.ptr, s1.ptr, n1);
672  memcpy(str.ptr + n1, s2.ptr, n2);
673  return str;
674}
675
676crunch_primitive crunch_unspecified crunch_string_2dfill_21(crunch_string &s, char c) { memset(s.ptr, c, s.length()); return 0; }
677
678crunch_local crunch_u8vector crunch_subu8vector(const crunch_u8vector &v, int n, int m) {
679  crunch_u8vector str(m - n, '\0');
680  memcpy(str.ptr, v.ptr + n, m - n);
681  return str;
682}
683
684crunch_local crunch_s8vector crunch_subs8vector(const crunch_s8vector &v, int n, int m) {
685  crunch_s8vector str(m - n, '\0');
686  memcpy(str.ptr, v.ptr + n, m - n);
687  return str;
688}
689
690crunch_local crunch_u16vector crunch_subu16vector(const crunch_u16vector &v, int n, int m) {
691  crunch_u16vector str(m - n, '\0');
692  memcpy(str.ptr, v.ptr + n, (m - n) * 2);
693  return str;
694}
695
696crunch_local crunch_s16vector crunch_subs16vector(const crunch_s16vector &v, int n, int m) {
697  crunch_s16vector str(m - n, '\0');
698  memcpy(str.ptr, v.ptr + n, (m - n) * 2);
699  return str;
700}
701
702crunch_local crunch_u32vector crunch_subu32vector(const crunch_u32vector &v, int n, int m) {
703  crunch_u32vector str(m - n, '\0');
704  memcpy(str.ptr, v.ptr + n, (m - n) * 4);
705  return str;
706}
707
708crunch_local crunch_s32vector crunch_subs32vector(const crunch_s32vector &v, int n, int m) {
709  crunch_s32vector str(m - n, '\0');
710  memcpy(str.ptr, v.ptr + n, (m - n) * 4);
711  return str;
712}
713
714crunch_local crunch_f32vector crunch_subf32vector(const crunch_f32vector &v, int n, int m) {
715  crunch_f32vector str(m - n, '\0');
716  memcpy(str.ptr, v.ptr + n, (m - n) * 4);
717  return str;
718}
719
720crunch_local crunch_f64vector crunch_subf64vector(const crunch_f64vector &v, int n, int m) {
721  crunch_f64vector str(m - n, '\0');
722  memcpy(str.ptr, v.ptr + n, (m - n) * 8);
723  return str;
724}
725
726#ifndef ___CHICKEN
727static int C_main_argc;
728static char **C_main_argv;
729#endif
730
731crunch_primitive int crunch_argc() { return C_main_argc; }
732crunch_primitive crunch_string crunch_argv_2dref(int n) { return C_main_argv[ n ]; }
733
734crunch_local crunch_string crunch_number_2d_3estring(int num, int radix) {
735  char *buf = (char *)crunch_malloc(65);
736  char *p;
737
738  switch(radix) {
739  case 2: 
740    buf[ 64 ] = '\0';
741    p = buf + 64;
742 
743    do {
744      *(--p) = (num & 1) ? '1' : '0';
745      num /= 2;
746    } while(num);
747
748    return crunch_string::fromcopy(p, strlen(p));
749
750  case 8:
751    sprintf(buf, "%o", num);
752    return crunch_string::fromcopy(buf, strlen(buf));
753
754  case 16:
755    sprintf(buf, "%x", num);
756    return crunch_string::fromcopy(buf, strlen(buf));
757
758  default:
759    sprintf(buf, "%d", num);
760    return crunch_string::fromcopy(buf, strlen(buf));
761  }
762}
763
764crunch_local crunch_string crunch_number_2d_3estring(double num, int radix) {
765  char *buf = (char *)crunch_malloc(65);
766  sprintf(buf, "%g", num);
767  return crunch_string::fromcopy(buf, strlen(buf));
768}
769
770template<class T> crunch_local void crunch_string_2d_3enumber(const crunch_string &s, int radix, T &result) {
771  char *ep;
772  char buf[ 64 ];
773  int len = s.length();
774  memcpy(buf, s.ptr, len);
775  buf[ len ] = '\0';
776
777  if(radix == 10) result = (T)strtod(buf, &ep);
778  else result = strtol(buf, NULL, radix);
779}
780
781template<> crunch_local void crunch_string_2d_3enumber(const crunch_string &s, int radix, int &result) {
782  char *ep;
783  char buf[ 64 ];
784  int len = s.length();
785  memcpy(buf, s.ptr, len);
786  buf[ len ] = '\0';
787  result = strtol(s.ptr, &ep, radix);
788}
789
790crunch_primitive char crunch_char_2dupcase(char c) { return toupper(c); }
791crunch_primitive char crunch_char_2ddowncase(char c) { return tolower(c); }
792crunch_primitive bool crunch_char_2dwhitespace_3f(char c) { return isspace(c); }
793crunch_primitive bool crunch_char_2dalphabetic_3f(char c) { return isalpha(c); }
794crunch_primitive bool crunch_char_2dnumeric_3f(char c) { return isdigit(c); }
795crunch_primitive bool crunch_char_2dupper_2dcase_3f(char c) { return islower(c); }
796crunch_primitive bool crunch_char_2dlower_2dcase_3f(char c) { return isupper(c); }
797
798
799#endif
Note: See TracBrowser for help on using the repository browser.