moving some flisp-specific code out of library
This commit is contained in:
		
							parent
							
								
									689ec946d8
								
							
						
					
					
						commit
						6ed61e66ac
					
				| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
#include "operators.c"
 | 
			
		||||
 | 
			
		||||
#ifdef BITS64
 | 
			
		||||
#define NWORDS(sz) (((sz)+7)>>3)
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								flisp.h
								
								
								
								
							
							
						
						
									
										28
									
								
								flisp.h
								
								
								
								
							| 
						 | 
				
			
			@ -208,6 +208,19 @@ typedef struct {
 | 
			
		|||
} cvtable_t;
 | 
			
		||||
 | 
			
		||||
/* functions needed to implement the value interface (cvtable_t) */
 | 
			
		||||
typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
 | 
			
		||||
               T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
 | 
			
		||||
 | 
			
		||||
#define N_NUMTYPES ((int)T_DOUBLE+1)
 | 
			
		||||
 | 
			
		||||
#ifdef BITS64
 | 
			
		||||
# define T_LONG T_INT64
 | 
			
		||||
# define T_ULONG T_UINT64
 | 
			
		||||
#else
 | 
			
		||||
# define T_LONG T_INT32
 | 
			
		||||
# define T_ULONG T_UINT32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
value_t relocate_lispvalue(value_t v);
 | 
			
		||||
void print_traverse(value_t v);
 | 
			
		||||
void fl_print_chr(char c, ios_t *f);
 | 
			
		||||
| 
						 | 
				
			
			@ -351,6 +364,21 @@ value_t mk_wchar(int32_t n);
 | 
			
		|||
value_t return_from_uint64(uint64_t Uaccum);
 | 
			
		||||
value_t return_from_int64(int64_t Saccum);
 | 
			
		||||
 | 
			
		||||
numerictype_t effective_numerictype(double r);
 | 
			
		||||
double conv_to_double(void *data, numerictype_t tag);
 | 
			
		||||
void conv_from_double(void *data, double d, numerictype_t tag);
 | 
			
		||||
int64_t conv_to_int64(void *data, numerictype_t tag);
 | 
			
		||||
uint64_t conv_to_uint64(void *data, numerictype_t tag);
 | 
			
		||||
int32_t conv_to_int32(void *data, numerictype_t tag);
 | 
			
		||||
uint32_t conv_to_uint32(void *data, numerictype_t tag);
 | 
			
		||||
#ifdef BITS64
 | 
			
		||||
#define conv_to_long conv_to_int64
 | 
			
		||||
#define conv_to_ulong conv_to_uint64
 | 
			
		||||
#else
 | 
			
		||||
#define conv_to_long conv_to_int32
 | 
			
		||||
#define conv_to_ulong conv_to_uint32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    char *name;
 | 
			
		||||
    builtin_t fptr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								llt/Makefile
								
								
								
								
							
							
						
						
									
										16
									
								
								llt/Makefile
								
								
								
								
							| 
						 | 
				
			
			@ -1,14 +1,11 @@
 | 
			
		|||
CC = gcc
 | 
			
		||||
 | 
			
		||||
SRCS = bitvector.c hashing.c socket.c timefuncs.c dblprint.c ptrhash.c \
 | 
			
		||||
	utf8.c ios.c operators.c cplxprint.c dirpath.c htable.c \
 | 
			
		||||
	bitvector-ops.c int2str.c dump.c random.c bswap.c memalign.c \
 | 
			
		||||
	swapreverse.c lltinit.c arraylist.c
 | 
			
		||||
SRCS = bitvector.c hashing.c socket.c timefuncs.c ptrhash.c utf8.c ios.c \
 | 
			
		||||
	dirpath.c htable.c bitvector-ops.c int2str.c dump.c random.c \
 | 
			
		||||
	lltinit.c arraylist.c
 | 
			
		||||
OBJS = $(SRCS:%.c=%.o)
 | 
			
		||||
DOBJS = $(SRCS:%.c=%.do)
 | 
			
		||||
TARGET = libllt.a
 | 
			
		||||
TESTSRC = unittest.c
 | 
			
		||||
TESTER = llttest
 | 
			
		||||
 | 
			
		||||
# OS flags: LINUX, WIN32, MACOSX
 | 
			
		||||
# architecture flags: __CPU__=xxx, BITS64, ARCH_X86, ARCH_X86_64
 | 
			
		||||
| 
						 | 
				
			
			@ -34,16 +31,9 @@ release: $(OBJS)
 | 
			
		|||
	rm -rf $(TARGET)
 | 
			
		||||
	ar rs $(TARGET) $(OBJS)
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	make clean
 | 
			
		||||
	make debug CFLAGS=-DENABLE_LLT_TEST
 | 
			
		||||
	gcc $(TESTSRC) $(TARGET) -o $(TESTER) -lm
 | 
			
		||||
	./$(TESTER)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f *.o
 | 
			
		||||
	rm -f *.do
 | 
			
		||||
	rm -f *~
 | 
			
		||||
	rm -f core*
 | 
			
		||||
	rm -f $(TARGET)
 | 
			
		||||
	rm -f $(TESTER)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										87
									
								
								llt/bswap.c
								
								
								
								
							
							
						
						
									
										87
									
								
								llt/bswap.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,87 +0,0 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <alloca.h>
 | 
			
		||||
#include "dtypes.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
void bswap_buffer(byte_t *data, size_t sz, size_t npts)
 | 
			
		||||
{
 | 
			
		||||
    size_t i, b;
 | 
			
		||||
    byte_t *el;
 | 
			
		||||
    byte_t temp;
 | 
			
		||||
 | 
			
		||||
    if (sz <= 1)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    switch (sz) {
 | 
			
		||||
    case 8:
 | 
			
		||||
        for(i=0; i < npts; i++) {
 | 
			
		||||
            ((u_int64_t*)data)[i] = bswap_64(((u_int64_t*)data)[i]);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        for(i=0; i < npts; i++) {
 | 
			
		||||
            ((u_int32_t*)data)[i] = bswap_32(((u_int32_t*)data)[i]);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        for(i=0; i < npts; i++) {
 | 
			
		||||
            ((u_int16_t*)data)[i] = bswap_16(((u_int16_t*)data)[i]);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        for(i=0; i < sz * npts; i += sz) {
 | 
			
		||||
            el = data + i;
 | 
			
		||||
            for(b=0; b < sz/2; b++) {
 | 
			
		||||
                temp = el[b];
 | 
			
		||||
                el[b] = el[sz-b-1];
 | 
			
		||||
                el[sz-b-1] = temp;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bswap(byte_t *s, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
    char temp;
 | 
			
		||||
 | 
			
		||||
    switch (n) {
 | 
			
		||||
    case 8:
 | 
			
		||||
        *(u_int64_t*)s = bswap_64(*(u_int64_t*)s); break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        *(u_int32_t*)s = bswap_32(*(u_int32_t*)s); break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        *(u_int16_t*)s = bswap_16(*(u_int16_t*)s); break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            temp = s[i];
 | 
			
		||||
            s[i] = s[n-i-1];
 | 
			
		||||
            s[n-i-1] = temp;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bswap_to(byte_t *dest, byte_t *src, size_t n)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int i;
 | 
			
		||||
 | 
			
		||||
    switch (n) {
 | 
			
		||||
    case 8:
 | 
			
		||||
        *(u_int64_t*)dest = bswap_64(*(u_int64_t*)src); break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        *(u_int32_t*)dest = bswap_32(*(u_int32_t*)src); break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        *(u_int16_t*)dest = bswap_16(*(u_int16_t*)src); break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        for(i=0; i < n; i++) {
 | 
			
		||||
            dest[i] = src[n-i-1];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,66 +0,0 @@
 | 
			
		|||
#include <math.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "dtypes.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
void snprint_cplx(char *s, size_t cnt, double re, double im,
 | 
			
		||||
                  // args to pass on to snprint_real
 | 
			
		||||
                  int width, int dec,
 | 
			
		||||
                  int max_digs_rt, int max_digs_lf,
 | 
			
		||||
                  // print spaces around sign in a+bi
 | 
			
		||||
                  int spflag)
 | 
			
		||||
{
 | 
			
		||||
    int fzr = (re==0) || rel_zero(re,im);
 | 
			
		||||
    int fzi = (im==0) || rel_zero(im,re);
 | 
			
		||||
    size_t len, sl;
 | 
			
		||||
    size_t space = cnt;
 | 
			
		||||
 | 
			
		||||
    s[0] = '\0';
 | 
			
		||||
    if (isnan(im) && fzr) {
 | 
			
		||||
        if (space < 2) return;
 | 
			
		||||
        snprint_real(s, space-2, im, width, dec, max_digs_rt, max_digs_lf);
 | 
			
		||||
        strcat(s, "i");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!fzr || (fzr && fzi)) {
 | 
			
		||||
        if (space < 4) return;
 | 
			
		||||
        snprint_real(s, space-4, re, width, dec, max_digs_rt, max_digs_lf);
 | 
			
		||||
        if ((im >= 0 || (isnan(im)&&!sign_bit(im))) && !fzi) {
 | 
			
		||||
            if (spflag) {
 | 
			
		||||
                strcat(s, " + ");
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                strcat(s, "+");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (!fzi) {
 | 
			
		||||
            im = -im;
 | 
			
		||||
            if (spflag)
 | 
			
		||||
                strcat(s, " - ");
 | 
			
		||||
            else
 | 
			
		||||
                strcat(s, "-");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (!fzi) {
 | 
			
		||||
        len = sl = strlen(s);
 | 
			
		||||
        if (im == -1) {
 | 
			
		||||
            while ((long)(len-sl) < (long)(width-2) && len < (space-3))
 | 
			
		||||
                s[len++] = ' ';
 | 
			
		||||
            s[len] =   '-';
 | 
			
		||||
            s[len+1] = 'i';
 | 
			
		||||
            s[len+2] = '\0';
 | 
			
		||||
        }
 | 
			
		||||
        else if (im == 1) {
 | 
			
		||||
            while ((long)(len-sl) < (long)(width-1) && len < (space-2))
 | 
			
		||||
                s[len++] = ' ';
 | 
			
		||||
            s[len] =   'i';
 | 
			
		||||
            s[len+1] = '\0';
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            snprint_real(s+len, space-len-2, im, width, dec,
 | 
			
		||||
                         max_digs_rt, max_digs_lf);
 | 
			
		||||
            strcat(s, "i");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								llt/dblprint.c
								
								
								
								
							
							
						
						
									
										122
									
								
								llt/dblprint.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
#include <math.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include "dtypes.h"
 | 
			
		||||
#include "ieee754.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
int double_exponent(double d)
 | 
			
		||||
{
 | 
			
		||||
    union ieee754_double dl;
 | 
			
		||||
 | 
			
		||||
    dl.d = d;
 | 
			
		||||
    return dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double double_mantissa(double d)
 | 
			
		||||
{
 | 
			
		||||
    union ieee754_double dl;
 | 
			
		||||
 | 
			
		||||
    dl.d = d;
 | 
			
		||||
    dl.ieee.exponent = IEEE754_DOUBLE_BIAS;
 | 
			
		||||
    dl.ieee.negative = 0;
 | 
			
		||||
    return dl.d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int float_exponent(float f)
 | 
			
		||||
{
 | 
			
		||||
    union ieee754_float fl;
 | 
			
		||||
 | 
			
		||||
    fl.f = f;
 | 
			
		||||
    return fl.ieee.exponent - IEEE754_FLOAT_BIAS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float float_mantissa(float f)
 | 
			
		||||
{
 | 
			
		||||
    union ieee754_float fl;
 | 
			
		||||
 | 
			
		||||
    fl.f = f;
 | 
			
		||||
    fl.ieee.exponent = IEEE754_FLOAT_BIAS;
 | 
			
		||||
    fl.ieee.negative = 0;
 | 
			
		||||
    return fl.f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void snprint_real(char *s, size_t cnt, double r,
 | 
			
		||||
                  int width,    // printf field width, or 0
 | 
			
		||||
                  int dec,      // # decimal digits desired, recommend 16
 | 
			
		||||
                  // # of zeros in .00...0x before using scientific notation
 | 
			
		||||
                  // recommend 3-4 or so
 | 
			
		||||
                  int max_digs_rt,
 | 
			
		||||
                  // # of digits left of decimal before scientific notation
 | 
			
		||||
                  // recommend 10
 | 
			
		||||
                  int max_digs_lf)
 | 
			
		||||
{
 | 
			
		||||
    int mag;
 | 
			
		||||
    double fpart, temp;
 | 
			
		||||
    char format[8];
 | 
			
		||||
    char num_format[3];
 | 
			
		||||
    int sz, keepz=0;
 | 
			
		||||
 | 
			
		||||
    s[0] = '\0';
 | 
			
		||||
    if (width == -1) {
 | 
			
		||||
        width = 0;
 | 
			
		||||
        keepz=1;
 | 
			
		||||
    }
 | 
			
		||||
    if (isnan(r)) {
 | 
			
		||||
        if (sign_bit(r))
 | 
			
		||||
            strncpy(s, "-nan", cnt);
 | 
			
		||||
        else
 | 
			
		||||
            strncpy(s, "nan", cnt);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (r == 0) {
 | 
			
		||||
        strncpy(s, "0", cnt);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    num_format[0] = 'l';
 | 
			
		||||
    num_format[2] = '\0';
 | 
			
		||||
 | 
			
		||||
    mag = double_exponent(r);
 | 
			
		||||
 | 
			
		||||
    mag = (int)(((double)mag)/LOG2_10 + 0.5);
 | 
			
		||||
    if (r == 0)
 | 
			
		||||
        mag = 0;
 | 
			
		||||
    if ((mag > max_digs_lf-1) || (mag < -max_digs_rt)) {
 | 
			
		||||
        num_format[1] = 'e';
 | 
			
		||||
        temp = r/pow(10, mag);      /* see if number will have a decimal */
 | 
			
		||||
        fpart = temp - floor(temp); /* when written in scientific notation */
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        num_format[1] = 'f';
 | 
			
		||||
        fpart = r - floor(r);
 | 
			
		||||
    }
 | 
			
		||||
    if (fpart == 0)
 | 
			
		||||
        dec = 0;
 | 
			
		||||
    if (width == 0) {
 | 
			
		||||
        snprintf(format, 8, "%%.%d%s", dec, num_format);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        snprintf(format, 8, "%%%d.%d%s", width, dec, num_format);
 | 
			
		||||
    }
 | 
			
		||||
    sz = snprintf(s, cnt, format, r);
 | 
			
		||||
    /* trim trailing zeros from fractions. not when using scientific
 | 
			
		||||
       notation, since we might have e.g. 1.2000e+100. also not when we
 | 
			
		||||
       need a specific output width */
 | 
			
		||||
    if (width == 0 && !keepz) {
 | 
			
		||||
        if (sz > 2 && fpart && num_format[1]!='e') {
 | 
			
		||||
            while (s[sz-1] == '0') {
 | 
			
		||||
                s[sz-1]='\0';
 | 
			
		||||
                sz--;
 | 
			
		||||
            }
 | 
			
		||||
            // don't need trailing .
 | 
			
		||||
            if (s[sz-1] == '.') {
 | 
			
		||||
                s[sz-1] = '\0';
 | 
			
		||||
                sz--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // TODO. currently 1.1e20 prints as 1.1000000000000000e+20; be able to
 | 
			
		||||
    // get rid of all those zeros.
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								llt/dtypes.h
								
								
								
								
							
							
						
						
									
										13
									
								
								llt/dtypes.h
								
								
								
								
							| 
						 | 
				
			
			@ -178,17 +178,4 @@ extern float  F_NNAN;
 | 
			
		|||
extern float  F_PINF;
 | 
			
		||||
extern float  F_NINF;
 | 
			
		||||
 | 
			
		||||
typedef enum { T_INT8, T_UINT8, T_INT16, T_UINT16, T_INT32, T_UINT32,
 | 
			
		||||
               T_INT64, T_UINT64, T_FLOAT, T_DOUBLE } numerictype_t;
 | 
			
		||||
 | 
			
		||||
#define N_NUMTYPES ((int)T_DOUBLE+1)
 | 
			
		||||
 | 
			
		||||
#ifdef BITS64
 | 
			
		||||
# define T_LONG T_INT64
 | 
			
		||||
# define T_ULONG T_UINT64
 | 
			
		||||
#else
 | 
			
		||||
# define T_LONG T_INT32
 | 
			
		||||
# define T_ULONG T_UINT32
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,50 +0,0 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <alloca.h>
 | 
			
		||||
#include "dtypes.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
#define ALIGNED_TO_ACTUAL(p) (((char*)p) - ((long*)p)[-1])
 | 
			
		||||
 | 
			
		||||
static void *aligned_ptr(char *ptr, size_t align_size)
 | 
			
		||||
{
 | 
			
		||||
    char *ptr2, *aligned_ptr;
 | 
			
		||||
 | 
			
		||||
    ptr2 = ptr + sizeof(long);
 | 
			
		||||
    aligned_ptr = (char*)LLT_ALIGN(((uptrint_t)ptr2), align_size);
 | 
			
		||||
 | 
			
		||||
    ((long*)aligned_ptr)[-1] = (long)(aligned_ptr - ptr);
 | 
			
		||||
 | 
			
		||||
    return aligned_ptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* align_size has to be a power of two */
 | 
			
		||||
void *malloc_aligned(size_t size, size_t align_size)
 | 
			
		||||
{
 | 
			
		||||
    char *ptr;
 | 
			
		||||
 | 
			
		||||
    ptr = (char*)LLT_ALLOC(size + align_size-1 + sizeof(long));
 | 
			
		||||
    if (ptr == NULL)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    return aligned_ptr(ptr, align_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void free_aligned(void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    LLT_FREE(ALIGNED_TO_ACTUAL(ptr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *realloc_aligned(void *ptr, size_t size, size_t align_size)
 | 
			
		||||
{
 | 
			
		||||
    char *pnew;
 | 
			
		||||
 | 
			
		||||
    if (ptr != NULL)
 | 
			
		||||
        ptr = ALIGNED_TO_ACTUAL(ptr);
 | 
			
		||||
    pnew = LLT_REALLOC(ptr, size + align_size-1 + sizeof(long));
 | 
			
		||||
    if (pnew == NULL)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    return aligned_ptr(pnew, align_size);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,187 +0,0 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <alloca.h>
 | 
			
		||||
#include "dtypes.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
void memswap(char *a, char *b, size_t sz)
 | 
			
		||||
{
 | 
			
		||||
    int8_t i8;
 | 
			
		||||
    int32_t i32;
 | 
			
		||||
    int32_t *a4, *b4;
 | 
			
		||||
 | 
			
		||||
    if (sz < 4) {
 | 
			
		||||
        while (sz--) {
 | 
			
		||||
            i8 = *a;
 | 
			
		||||
            *a++ = *b;
 | 
			
		||||
            *b++ = i8;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        while (sz & 0x3) {
 | 
			
		||||
            i8 = *a;
 | 
			
		||||
            *a++ = *b;
 | 
			
		||||
            *b++ = i8;
 | 
			
		||||
            sz--;
 | 
			
		||||
        }
 | 
			
		||||
        a4 = (int32_t*)a;
 | 
			
		||||
        b4 = (int32_t*)b;
 | 
			
		||||
        sz >>= 2;
 | 
			
		||||
        while (sz--) {
 | 
			
		||||
            i32 = *a4;
 | 
			
		||||
            *a4++ = *b4;
 | 
			
		||||
            *b4++ = i32;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void memreverse(char *a, size_t n, size_t elsz)
 | 
			
		||||
{
 | 
			
		||||
    int64_t i64, *pi64;
 | 
			
		||||
    int32_t i32, *pi32;
 | 
			
		||||
    int16_t i16, *pi16;
 | 
			
		||||
    int8_t i8;
 | 
			
		||||
    size_t i;
 | 
			
		||||
    char *temp;
 | 
			
		||||
    size_t eli, tot;
 | 
			
		||||
 | 
			
		||||
    if (n==0 || elsz==0) return;
 | 
			
		||||
    switch(elsz) {
 | 
			
		||||
    case 16:
 | 
			
		||||
        pi64 = (int64_t*)a;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            i64 = pi64[2*i];
 | 
			
		||||
            pi64[2*i] = pi64[2*(n-i-1)];
 | 
			
		||||
            pi64[2*(n-i-1)] = i64;
 | 
			
		||||
 | 
			
		||||
            i64 = pi64[2*i+1];
 | 
			
		||||
            pi64[2*i+1] = pi64[2*(n-i-1)+1];
 | 
			
		||||
            pi64[2*(n-i-1)+1] = i64;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 8:
 | 
			
		||||
        pi64 = (int64_t*)a;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            i64 = pi64[i];
 | 
			
		||||
            pi64[i] = pi64[n-i-1];
 | 
			
		||||
            pi64[n-i-1] = i64;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        pi32 = (int32_t*)a;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            i32 = pi32[i];
 | 
			
		||||
            pi32[i] = pi32[n-i-1];
 | 
			
		||||
            pi32[n-i-1] = i32;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        pi16 = (int16_t*)a;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            i16 = pi16[i];
 | 
			
		||||
            pi16[i] = pi16[n-i-1];
 | 
			
		||||
            pi16[n-i-1] = i16;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            i8 = a[i];
 | 
			
		||||
            a[i] = a[n-i-1];
 | 
			
		||||
            a[n-i-1] = i8;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        tot = n*elsz;
 | 
			
		||||
        if (elsz < 4097)
 | 
			
		||||
            temp = alloca(elsz);
 | 
			
		||||
        else
 | 
			
		||||
            temp = malloc(elsz);
 | 
			
		||||
 | 
			
		||||
        if (temp != NULL) {
 | 
			
		||||
            for(i=0, eli=0; i < n/2; i++, eli+=elsz) {
 | 
			
		||||
                memcpy(temp, &a[eli], elsz);
 | 
			
		||||
                memcpy(&a[eli], &a[tot-eli-elsz], elsz);
 | 
			
		||||
                memcpy(&a[tot-eli-elsz], temp, elsz);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (elsz >= 4097)
 | 
			
		||||
                free(temp);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void memreverse_to(char *dest, char *a, size_t n, size_t elsz)
 | 
			
		||||
{
 | 
			
		||||
    int64_t *pi64, *di64;
 | 
			
		||||
    int32_t *pi32, *di32;
 | 
			
		||||
    int16_t *pi16, *di16;
 | 
			
		||||
    size_t i;
 | 
			
		||||
    size_t eli, tot;
 | 
			
		||||
    if (n==0 || elsz==0) return;
 | 
			
		||||
    switch(elsz) {
 | 
			
		||||
    case 16:
 | 
			
		||||
        pi64 = (int64_t*)a;
 | 
			
		||||
        di64 = (int64_t*)dest;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            di64[2*i] = pi64[2*(n-i-1)];
 | 
			
		||||
            di64[2*(n-i-1)] = pi64[2*i];
 | 
			
		||||
 | 
			
		||||
            di64[2*i+1] = pi64[2*(n-i-1)+1];
 | 
			
		||||
            di64[2*(n-i-1)+1] = pi64[2*i+1];
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1) {
 | 
			
		||||
            di64[2*i] = pi64[2*i];
 | 
			
		||||
            di64[2*i+1] = pi64[2*i+1];
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case 8:
 | 
			
		||||
        pi64 = (int64_t*)a;
 | 
			
		||||
        di64 = (int64_t*)dest;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            di64[i] = pi64[n-i-1];
 | 
			
		||||
            di64[n-i-1] = pi64[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1)
 | 
			
		||||
            di64[i] = pi64[i];
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        pi32 = (int32_t*)a;
 | 
			
		||||
        di32 = (int32_t*)dest;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            di32[i] = pi32[n-i-1];
 | 
			
		||||
            di32[n-i-1] = pi32[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1)
 | 
			
		||||
            di32[i] = pi32[i];
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        pi16 = (int16_t*)a;
 | 
			
		||||
        di16 = (int16_t*)dest;
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            di16[i] = pi16[n-i-1];
 | 
			
		||||
            di16[n-i-1] = pi16[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1)
 | 
			
		||||
            di16[i] = pi16[i];
 | 
			
		||||
        break;
 | 
			
		||||
    case 1:
 | 
			
		||||
        for(i=0; i < n/2; i++) {
 | 
			
		||||
            dest[i] = a[n-i-1];
 | 
			
		||||
            dest[n-i-1] = a[i];
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1)
 | 
			
		||||
            dest[i] = a[i];
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        tot = n*elsz;
 | 
			
		||||
        for(i=0, eli=0; i < n/2; i++, eli+=elsz) {
 | 
			
		||||
            memcpy(&dest[eli], &a[tot - eli - elsz], elsz);
 | 
			
		||||
            memcpy(&dest[tot - eli - elsz], &a[eli], elsz);
 | 
			
		||||
        }
 | 
			
		||||
        if (n&0x1)
 | 
			
		||||
            memcpy(&dest[eli], &a[eli], elsz);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										142
									
								
								llt/unittest.c
								
								
								
								
							
							
						
						
									
										142
									
								
								llt/unittest.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,142 +0,0 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <wchar.h>
 | 
			
		||||
#include "llt.h"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    llt_init();
 | 
			
		||||
 | 
			
		||||
    test_dblprint();
 | 
			
		||||
    test_operators();
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    char *buf = malloc(20000);
 | 
			
		||||
    char *buf2 = malloc(20000);
 | 
			
		||||
    FILE *f = fopen("textread.m","rb");
 | 
			
		||||
    int i=0;
 | 
			
		||||
    while (!feof(f))
 | 
			
		||||
      buf[i++] = fgetc(f);
 | 
			
		||||
    buf[i-1] = '\0';
 | 
			
		||||
    int len = i-1;
 | 
			
		||||
    double t0 = clock_now();
 | 
			
		||||
    int j=0;
 | 
			
		||||
    for(i=0; i < 20000; i++) {
 | 
			
		||||
        //j+=u8_charnum(buf,len);
 | 
			
		||||
        u8_reverse(buf2, buf, len);
 | 
			
		||||
    }
 | 
			
		||||
    printf("textread took %.4f sec (%d)\n", clock_now()-t0, j);
 | 
			
		||||
 | 
			
		||||
    FILE *f2 = fopen("u8.txt","rb");
 | 
			
		||||
    i=0;
 | 
			
		||||
    while (!feof(f2))
 | 
			
		||||
      buf[i++] = fgetc(f2);
 | 
			
		||||
    buf[i-1] = '\0';
 | 
			
		||||
    len = i-1;
 | 
			
		||||
    t0 = clock_now();
 | 
			
		||||
    j=0;
 | 
			
		||||
    for(i=0; i < 20000; i++) {
 | 
			
		||||
        //j+=u8_charnum(buf,len);
 | 
			
		||||
        u8_reverse(buf2, buf, len);
 | 
			
		||||
    }
 | 
			
		||||
    printf("u8 took %.4f sec (%d)\n\n", clock_now()-t0, j);
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
    test_ios();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prettycplx(double r, double i)
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
    snprint_cplx(str, sizeof(str), r, i, 0, 16, 3, 10, 1);
 | 
			
		||||
    fputs(str, stdout);
 | 
			
		||||
    fputc('\n', stdout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prettyreal(double r)
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
    snprint_real(str, sizeof(str), r, 0, 16, 3, 10);
 | 
			
		||||
    fputs(str, stdout);
 | 
			
		||||
    fputc('\n', stdout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_dblprint()
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
 | 
			
		||||
    prettycplx(0,0);
 | 
			
		||||
    prettycplx(1,0);
 | 
			
		||||
    prettycplx(0,1);
 | 
			
		||||
    prettycplx(1,1);
 | 
			
		||||
    prettycplx(-1,0);
 | 
			
		||||
    prettycplx(0,-1);
 | 
			
		||||
    prettycplx(1,-1);
 | 
			
		||||
    prettycplx(-1,1);
 | 
			
		||||
    prettycplx(-1,-1);
 | 
			
		||||
    prettycplx(2,0);
 | 
			
		||||
    prettycplx(0,2);
 | 
			
		||||
    prettycplx(2,2);
 | 
			
		||||
    prettycplx(-2,0);
 | 
			
		||||
    prettycplx(0,-2);
 | 
			
		||||
    prettycplx(2,-2);
 | 
			
		||||
    prettycplx(-2,2);
 | 
			
		||||
    prettycplx(-2,-2);
 | 
			
		||||
 | 
			
		||||
    prettyreal(1.5);
 | 
			
		||||
    prettyreal(1.1);
 | 
			
		||||
    prettyreal(1.1e-100);
 | 
			
		||||
    prettyreal(1.1e20);
 | 
			
		||||
    prettyreal(123456789);
 | 
			
		||||
    prettyreal(1234567890);
 | 
			
		||||
    prettyreal(12345678901);
 | 
			
		||||
    prettyreal(-12345678901);
 | 
			
		||||
    prettyreal(12345678901223);
 | 
			
		||||
    prettyreal(-12345678901223);
 | 
			
		||||
    prettyreal(.02);
 | 
			
		||||
    prettyreal(.002);
 | 
			
		||||
    prettyreal(.0002);
 | 
			
		||||
    prettyreal(-.0002);
 | 
			
		||||
    prettyreal(.00002);
 | 
			
		||||
    prettyreal(-.00002);
 | 
			
		||||
 | 
			
		||||
    prettyreal(1.0/0);
 | 
			
		||||
    prettyreal(-1.0/0);
 | 
			
		||||
    prettyreal(strtod("nan",NULL));
 | 
			
		||||
    prettyreal(0.0/0);
 | 
			
		||||
    prettyreal(-0.0/0);
 | 
			
		||||
 | 
			
		||||
    prettyreal(DBL_EPSILON);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_ios()
 | 
			
		||||
{
 | 
			
		||||
    ios_t *out = ios_stdout();
 | 
			
		||||
    ios_t *in = ios_stdin();
 | 
			
		||||
 | 
			
		||||
    ios_putc('a', out);
 | 
			
		||||
    ios_putc('b', out);
 | 
			
		||||
    ios_putc('\n', out);
 | 
			
		||||
 | 
			
		||||
    char c[80];
 | 
			
		||||
    size_t i=0;
 | 
			
		||||
    ios_t sts;
 | 
			
		||||
    ios_str(&sts, "Test string.");
 | 
			
		||||
    c[i++] = ios_getc(&sts);
 | 
			
		||||
    c[i++] = ios_getc(&sts);
 | 
			
		||||
    c[i++] = ios_getc(&sts);
 | 
			
		||||
    c[i++] = '\0';
 | 
			
		||||
    printf("got: \"%s\"\n", c);
 | 
			
		||||
 | 
			
		||||
    ios_t ms;
 | 
			
		||||
    ios_mem(&ms, 10);
 | 
			
		||||
    int j;
 | 
			
		||||
    for(j=0; j < 16; j++)
 | 
			
		||||
        ios_puts("passersby were amazed by the ", &ms);
 | 
			
		||||
    size_t bs;
 | 
			
		||||
    char *bigstr = ios_takebuf(&ms, &bs);
 | 
			
		||||
    printf("got: \"%s\" (size %d)\n", bigstr, bs);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,81 +0,0 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <wchar.h>
 | 
			
		||||
#include "llt.h"
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    llt_init();
 | 
			
		||||
 | 
			
		||||
    test_dblprint();
 | 
			
		||||
    test_operators();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prettycplx(double r, double i)
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
    snprint_cplx(str, sizeof(str), r, i, 0, 16, 3, 10, 1);
 | 
			
		||||
    fputs(str, stdout);
 | 
			
		||||
    fputc('\n', stdout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prettyreal(double r)
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
    snprint_real(str, sizeof(str), r, 0, 16, 3, 10);
 | 
			
		||||
    fputs(str, stdout);
 | 
			
		||||
    fputc('\n', stdout);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void test_dblprint()
 | 
			
		||||
{
 | 
			
		||||
    char str[64];
 | 
			
		||||
 | 
			
		||||
    dbl_tolerance(1e-12);
 | 
			
		||||
 | 
			
		||||
    prettycplx(0,0);
 | 
			
		||||
    prettycplx(1,0);
 | 
			
		||||
    prettycplx(0,1);
 | 
			
		||||
    prettycplx(1,1);
 | 
			
		||||
    prettycplx(-1,0);
 | 
			
		||||
    prettycplx(0,-1);
 | 
			
		||||
    prettycplx(1,-1);
 | 
			
		||||
    prettycplx(-1,1);
 | 
			
		||||
    prettycplx(-1,-1);
 | 
			
		||||
    prettycplx(2,0);
 | 
			
		||||
    prettycplx(0,2);
 | 
			
		||||
    prettycplx(2,2);
 | 
			
		||||
    prettycplx(-2,0);
 | 
			
		||||
    prettycplx(0,-2);
 | 
			
		||||
    prettycplx(2,-2);
 | 
			
		||||
    prettycplx(-2,2);
 | 
			
		||||
    prettycplx(-2,-2);
 | 
			
		||||
 | 
			
		||||
    prettyreal(1.5);
 | 
			
		||||
    prettyreal(1.1);
 | 
			
		||||
    prettyreal(1.1e-100);
 | 
			
		||||
    prettyreal(1.1e20);
 | 
			
		||||
    prettyreal(123456789);
 | 
			
		||||
    prettyreal(1234567890);
 | 
			
		||||
    prettyreal(12345678901);
 | 
			
		||||
    prettyreal(-12345678901);
 | 
			
		||||
    prettyreal(12345678901223);
 | 
			
		||||
    prettyreal(-12345678901223);
 | 
			
		||||
    prettyreal(.02);
 | 
			
		||||
    prettyreal(.002);
 | 
			
		||||
    prettyreal(.0002);
 | 
			
		||||
    prettyreal(-.0002);
 | 
			
		||||
    prettyreal(.00002);
 | 
			
		||||
    prettyreal(-.00002);
 | 
			
		||||
 | 
			
		||||
    prettyreal(1.0/0);
 | 
			
		||||
    prettyreal(-1.0/0);
 | 
			
		||||
    prettyreal(strtod("nan",NULL));
 | 
			
		||||
    prettyreal(0.0/0);
 | 
			
		||||
    prettyreal(-0.0/0);
 | 
			
		||||
 | 
			
		||||
    prettyreal(DBL_EPSILON);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								llt/utils.h
								
								
								
								
							
							
						
						
									
										69
									
								
								llt/utils.h
								
								
								
								
							| 
						 | 
				
			
			@ -1,79 +1,10 @@
 | 
			
		|||
#ifndef __UTILS_H_
 | 
			
		||||
#define __UTILS_H_
 | 
			
		||||
 | 
			
		||||
/* these functions byteswap any-size units --------------------- */
 | 
			
		||||
void bswap(byte_t *s, size_t n);
 | 
			
		||||
void bswap_to(byte_t *dest, byte_t *src, size_t n);
 | 
			
		||||
void bswap_buffer(byte_t *data, size_t sz, size_t npts);
 | 
			
		||||
/* ------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* reverse the order of elements of any size, in place or out of place */
 | 
			
		||||
/* n is the number of elements */
 | 
			
		||||
void memreverse(char *a, size_t n, size_t elsz);
 | 
			
		||||
void memreverse_to(char *dest, char *a, size_t n, size_t elsz);
 | 
			
		||||
 | 
			
		||||
/* swap the contents of two buffers */
 | 
			
		||||
void memswap(char *a, char *b, size_t sz);
 | 
			
		||||
 | 
			
		||||
/* allocating aligned blocks ----------------------------------- */
 | 
			
		||||
void *malloc_aligned(size_t size, size_t align_size);
 | 
			
		||||
void free_aligned(void *ptr);
 | 
			
		||||
void *realloc_aligned(void *ptr, size_t size, size_t align_size);
 | 
			
		||||
/* ------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
int double_exponent(double d);
 | 
			
		||||
double double_mantissa(double d);
 | 
			
		||||
int float_exponent(float f);
 | 
			
		||||
float float_mantissa(float f);
 | 
			
		||||
void snprint_real(char *s, size_t cnt, double r,
 | 
			
		||||
                  int width,    // printf field width, or 0
 | 
			
		||||
                  int dec,      // # decimal digits desired, recommend 16
 | 
			
		||||
                  // # of zeros in .00...0x before using scientific notation
 | 
			
		||||
                  // recommend 3-4 or so
 | 
			
		||||
                  int max_digs_rt,
 | 
			
		||||
                  // # of digits left of decimal before scientific notation
 | 
			
		||||
                  // recommend 10
 | 
			
		||||
                  int max_digs_lf);
 | 
			
		||||
void snprint_cplx(char *s, size_t cnt, double re, double im,
 | 
			
		||||
                  // args to pass on to snprint_real
 | 
			
		||||
                  int width, int dec,
 | 
			
		||||
                  int max_digs_rt, int max_digs_lf,
 | 
			
		||||
                  // print spaces around sign in a+bi
 | 
			
		||||
                  int spflag);
 | 
			
		||||
 | 
			
		||||
char *uint2str(char *dest, size_t len, uint64_t num, uint32_t base);
 | 
			
		||||
int str2int(char *str, size_t len, int64_t *res, uint32_t base);
 | 
			
		||||
int isdigit_base(char c, int base);
 | 
			
		||||
 | 
			
		||||
extern double trunc(double x);
 | 
			
		||||
 | 
			
		||||
STATIC_INLINE double fpart(double arg)
 | 
			
		||||
{
 | 
			
		||||
    return arg - trunc(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ipart(x) trunc(x)
 | 
			
		||||
 | 
			
		||||
numerictype_t effective_numerictype(double r);
 | 
			
		||||
double conv_to_double(void *data, numerictype_t tag);
 | 
			
		||||
void conv_from_double(void *data, double d, numerictype_t tag);
 | 
			
		||||
int64_t conv_to_int64(void *data, numerictype_t tag);
 | 
			
		||||
uint64_t conv_to_uint64(void *data, numerictype_t tag);
 | 
			
		||||
int32_t conv_to_int32(void *data, numerictype_t tag);
 | 
			
		||||
uint32_t conv_to_uint32(void *data, numerictype_t tag);
 | 
			
		||||
#ifdef BITS64
 | 
			
		||||
#define conv_to_long conv_to_int64
 | 
			
		||||
#define conv_to_ulong conv_to_uint64
 | 
			
		||||
#else
 | 
			
		||||
#define conv_to_long conv_to_int32
 | 
			
		||||
#define conv_to_ulong conv_to_uint32
 | 
			
		||||
#endif
 | 
			
		||||
int cmp_same_lt(void *a, void *b, numerictype_t tag);
 | 
			
		||||
int cmp_same_eq(void *a, void *b, numerictype_t tag);
 | 
			
		||||
int cmp_lt(void *a, numerictype_t atag, void *b, numerictype_t btag);
 | 
			
		||||
int cmp_eq(void *a, numerictype_t atag, void *b, numerictype_t btag,
 | 
			
		||||
           int equalnans);
 | 
			
		||||
 | 
			
		||||
#ifdef ARCH_X86_64
 | 
			
		||||
#  define LEGACY_REGS "=Q"
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,13 @@
 | 
			
		|||
#include "utils.h"
 | 
			
		||||
#include "ieee754.h"
 | 
			
		||||
 | 
			
		||||
extern double trunc(double x);
 | 
			
		||||
 | 
			
		||||
STATIC_INLINE double fpart(double arg)
 | 
			
		||||
{
 | 
			
		||||
    return arg - trunc(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// given a number, determine an appropriate type for storing it
 | 
			
		||||
#if 0
 | 
			
		||||
numerictype_t effective_numerictype(double r)
 | 
			
		||||
							
								
								
									
										89
									
								
								print.c
								
								
								
								
							
							
						
						
									
										89
									
								
								print.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
#include "ieee754.h"
 | 
			
		||||
 | 
			
		||||
extern void *memrchr(const void *s, int c, size_t n);
 | 
			
		||||
 | 
			
		||||
static htable_t printconses;
 | 
			
		||||
| 
						 | 
				
			
			@ -518,6 +520,93 @@ static void print_string(ios_t *f, char *str, size_t sz)
 | 
			
		|||
    outc('"', f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int double_exponent(double d)
 | 
			
		||||
{
 | 
			
		||||
    union ieee754_double dl;
 | 
			
		||||
 | 
			
		||||
    dl.d = d;
 | 
			
		||||
    return dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void snprint_real(char *s, size_t cnt, double r,
 | 
			
		||||
                  int width,    // printf field width, or 0
 | 
			
		||||
                  int dec,      // # decimal digits desired, recommend 16
 | 
			
		||||
                  // # of zeros in .00...0x before using scientific notation
 | 
			
		||||
                  // recommend 3-4 or so
 | 
			
		||||
                  int max_digs_rt,
 | 
			
		||||
                  // # of digits left of decimal before scientific notation
 | 
			
		||||
                  // recommend 10
 | 
			
		||||
                  int max_digs_lf)
 | 
			
		||||
{
 | 
			
		||||
    int mag;
 | 
			
		||||
    double fpart, temp;
 | 
			
		||||
    char format[8];
 | 
			
		||||
    char num_format[3];
 | 
			
		||||
    int sz, keepz=0;
 | 
			
		||||
 | 
			
		||||
    s[0] = '\0';
 | 
			
		||||
    if (width == -1) {
 | 
			
		||||
        width = 0;
 | 
			
		||||
        keepz=1;
 | 
			
		||||
    }
 | 
			
		||||
    if (isnan(r)) {
 | 
			
		||||
        if (sign_bit(r))
 | 
			
		||||
            strncpy(s, "-nan", cnt);
 | 
			
		||||
        else
 | 
			
		||||
            strncpy(s, "nan", cnt);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (r == 0) {
 | 
			
		||||
        strncpy(s, "0", cnt);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    num_format[0] = 'l';
 | 
			
		||||
    num_format[2] = '\0';
 | 
			
		||||
 | 
			
		||||
    mag = double_exponent(r);
 | 
			
		||||
 | 
			
		||||
    mag = (int)(((double)mag)/LOG2_10 + 0.5);
 | 
			
		||||
    if (r == 0)
 | 
			
		||||
        mag = 0;
 | 
			
		||||
    if ((mag > max_digs_lf-1) || (mag < -max_digs_rt)) {
 | 
			
		||||
        num_format[1] = 'e';
 | 
			
		||||
        temp = r/pow(10, mag);      /* see if number will have a decimal */
 | 
			
		||||
        fpart = temp - floor(temp); /* when written in scientific notation */
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        num_format[1] = 'f';
 | 
			
		||||
        fpart = r - floor(r);
 | 
			
		||||
    }
 | 
			
		||||
    if (fpart == 0)
 | 
			
		||||
        dec = 0;
 | 
			
		||||
    if (width == 0) {
 | 
			
		||||
        snprintf(format, 8, "%%.%d%s", dec, num_format);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        snprintf(format, 8, "%%%d.%d%s", width, dec, num_format);
 | 
			
		||||
    }
 | 
			
		||||
    sz = snprintf(s, cnt, format, r);
 | 
			
		||||
    /* trim trailing zeros from fractions. not when using scientific
 | 
			
		||||
       notation, since we might have e.g. 1.2000e+100. also not when we
 | 
			
		||||
       need a specific output width */
 | 
			
		||||
    if (width == 0 && !keepz) {
 | 
			
		||||
        if (sz > 2 && fpart && num_format[1]!='e') {
 | 
			
		||||
            while (s[sz-1] == '0') {
 | 
			
		||||
                s[sz-1]='\0';
 | 
			
		||||
                sz--;
 | 
			
		||||
            }
 | 
			
		||||
            // don't need trailing .
 | 
			
		||||
            if (s[sz-1] == '.') {
 | 
			
		||||
                s[sz-1] = '\0';
 | 
			
		||||
                sz--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // TODO. currently 1.1e20 prints as 1.1000000000000000e+20; be able to
 | 
			
		||||
    // get rid of all those zeros.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static numerictype_t sym_to_numtype(value_t type);
 | 
			
		||||
 | 
			
		||||
// 'weak' means we don't need to accurately reproduce the type, so
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue