shithub: femtolisp

Download patch

ref: 518415febfea39229bf8a23ad2435009a8c88147
parent: 92542d0b78d27c0b4a17e4fffe2ca08ff5d3c63e
author: Jeff Bezanson <jeff.bezanson@gmail.com>
date: Tue Jun 11 14:15:48 EDT 2013

remove more unused stuff

--- a/llt/Makefile
+++ b/llt/Makefile
@@ -2,7 +2,7 @@
 
 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
+	lltinit.c
 OBJS = $(SRCS:%.c=%.o)
 DOBJS = $(SRCS:%.c=%.do)
 TARGET = libllt.a
--- a/llt/Makefile.macosx
+++ b/llt/Makefile.macosx
@@ -2,7 +2,7 @@
 
 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
+	lltinit.c
 OBJS = $(SRCS:%.c=%.o)
 DOBJS = $(SRCS:%.c=%.do)
 TARGET = libllt.a
--- a/llt/arraylist.c
+++ /dev/null
@@ -1,69 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <limits.h>
-
-#include "dtypes.h"
-#include "arraylist.h"
-
-arraylist_t *arraylist_new(arraylist_t *a, size_t size)
-{
-    a->len = 0;
-    if (size <= AL_N_INLINE) {
-        a->items = &a->_space[0];
-        a->max = AL_N_INLINE;
-    }
-    else {
-        a->items = (void**)LLT_ALLOC(size*sizeof(void*));
-        a->max = size;
-    }
-    if (a->items == NULL) return NULL;
-    return a;
-}
-
-void arraylist_free(arraylist_t *a)
-{
-    if (a->items != &a->_space[0])
-        LLT_FREE(a->items);
-    a->len = 0;
-    a->max = AL_N_INLINE;
-    a->items = &a->_space[0];
-}
-
-static void al_grow(arraylist_t *a, size_t n)
-{
-    if (a->len+n > a->max) {
-        if (a->items == &a->_space[0]) {
-            void **p = LLT_ALLOC((a->len+n)*sizeof(void*));
-            if (p == NULL) return;
-            memcpy(p, a->items, a->len*sizeof(void*));
-            a->items = p;
-            a->max = a->len+n;
-        }
-        else {
-            size_t nm = a->max*2;
-            if (nm == 0) nm = 1;
-            while (a->len+n > nm) nm*=2;
-            void **p = LLT_REALLOC(a->items, nm*sizeof(void*));
-            if (p == NULL) return;
-            a->items = p;
-            a->max = nm;
-        }
-    }
-    a->len += n;
-}
-
-void arraylist_push(arraylist_t *a, void *elt)
-{
-    al_grow(a, 1);
-    a->items[a->len-1] = elt;
-}
-
-void *arraylist_pop(arraylist_t *a)
-{
-    if (a->len == 0) return NULL;
-    void *p = a->items[--a->len];
-    a->items[a->len] = NULL;
-    return p;
-}
--- a/llt/arraylist.h
+++ /dev/null
@@ -1,19 +1,0 @@
-#ifndef __ARRAYLIST_H_
-#define __ARRAYLIST_H_
-
-#define AL_N_INLINE 29
-
-typedef struct {
-    size_t len;
-    size_t max;
-    void **items;
-    void *_space[AL_N_INLINE];
-} arraylist_t;
-
-arraylist_t *arraylist_new(arraylist_t *a, size_t size);
-void arraylist_free(arraylist_t *a);
-
-void arraylist_push(arraylist_t *a, void *elt);
-void *arraylist_pop(arraylist_t *a);
-
-#endif
--- a/llt/attic/ios.c.old
+++ /dev/null
@@ -1,396 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <limits.h>
-#include <errno.h>
-
-#ifdef WIN32
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#define fileno _fileno
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#endif
-
-#include "dtypes.h"
-#include "utils.h"
-#include "utf8.h"
-#include "ios.h"
-#include "socket.h"
-
-/* OS-level primitive wrappers */
-
-// return error code, #bytes read in *nread
-static int _os_read(long fd, void *buf, size_t n, size_t *nread)
-{
-    ssize_t r = read((int)fd, buf, n);
-    if (r == -1) {
-        *nread = 0;
-        return errno;
-    }
-    *nread = (size_t)r;
-    return 0;
-}
-
-static int _os_write(long fd, void *buf, size_t n, size_t *nwritten)
-{
-    ssize_t r = write((int)fd, buf, n);
-    if (r == -1) {
-        *nwritten = 0;
-        return errno;
-    }
-    *nread = (size_t)r;
-    return 0;
-}
-
-static int _fd_available(long fd)
-{
-#ifndef WIN32
-    fd_set set;
-    struct timeval tv = {0, 0};
-
-    FD_ZERO(&set);
-    FD_SET(fd, &set);
-    return (select(fd+1, &set, NULL, NULL, &tv)!=0);
-#else
-    return 0;
-#endif
-}
-
-
-/* internal utility functions */
-
-static char *_buf_realloc(ios_t *s, size_t sz)
-{
-    char *temp;
-
-    if (sz <= s->maxsize)
-        return s->buf;
-
-    if ((s->buf==NULL || s->buf==&s->local[0]) && (sz <= IOS_INLSIZE)) {
-        /* TODO: if we want to allow shrinking, see if the buffer shrank
-           down to this size, in which case we need to copy. */
-        s->buf = &s->local[0];
-        s->maxsize = IOS_INLSIZE;
-        s->ownbuf = 1;
-        return s->buf;
-    }
-    else if (s->ownbuf && s->buf != &s->local[0]) {
-        // if we own the buffer we're free to resize it
-        // always allocate 1 bigger in case user wants to add a NUL
-        // terminator after taking over the buffer
-        temp = realloc(s->buf, sz+1);
-        if (temp == NULL)
-            return NULL;
-    }
-    else {
-        temp = malloc(sz+1);
-        s->ownbuf = 1;
-        if (temp == NULL)
-            return NULL;
-    }
-
-    if (s->buf != temp && s->size > 0)
-        memcpy(temp, s->buf, s->size);
-    s->buf = temp;
-    s->maxsize = sz;
-    return s->buf;
-}
-
-// write a block of data into the buffer at the current position, resizing
-// if necessary. returns # written.
-static size_t _writebuf_force(ios_t *s, char *data, size_t n)
-{
-    size_t amt;
-    size_t newsize;
-
-    if (n == 0)
-        return 0;
-
-    if (s->bpos + n > s->size) {
-        if (s->bpos + n > s->maxsize) {
-            /* TO DO: here you might want to add a mechanism for limiting
-               the growth of the stream. */
-            newsize = s->maxsize * 2;
-            while (s->bpos + n > newsize)
-                newsize *= 2;
-            if (_buf_realloc(s, newsize) == NULL) {
-                /* no more space; write as much as we can */
-                amt = s->maxsize - s->bpos;
-                if (amt > 0) {
-                    memcpy(&s->buf[s->bpos], data, amt);
-                }
-                s->bpos += amt;
-                s->size = s->maxsize;
-                return amt;
-            }
-        }
-        s->size = s->bpos + n;
-    }
-    memcpy(&s->buf[s->bpos], data, n);
-    s->bpos += n;
-
-    return n;
-}
-
-
-/* interface functions, low level */
-
-size_t ios_read(ios_t *s, char *dest, size_t n)
-{
-}
-
-size_t ios_write(ios_t *s, char *data, size_t n)
-{
-}
-
-off_t ios_seek(ios_t *s, off_t pos)
-{
-}
-
-off_t ios_seek_end(ios_t *s)
-{
-}
-
-off_t ios_skip(ios_t *s, off_t offs)
-{
-}
-
-off_t ios_pos(ios_t *s)
-{
-    if (s->bm == bm_mem)
-        return (off_t)s->bpos;
-
-    off_t fdpos = lseek(s->fd, 0, SEEK_CUR);
-    if (fdpos == (off_t)-1)
-        return fdpos;
-
-    if (s->state == iost_wr)
-        fdpos += s->bpos;
-    else if (s->state == iost_rd)
-        fdpos -= (s->size - s->bpos);
-    return fdpos;
-}
-
-size_t ios_trunc(ios_t *s, size_t size)
-{
-}
-
-int ios_eof(ios_t *s)
-{
-    if (s->bm == bm_mem)
-        return (s->bpos >= s->size);
-    if (s->fd == -1)
-        return 1;
-    // todo
-}
-
-static void _discard_partial_buffer(ios_t *s)
-{
-    // this function preserves the invariant that data to write
-    // begins at the beginning of the buffer, and s->size refers
-    // to how much valid file data is stored in the buffer.
-
-    // this needs to be called when normal operation is interrupted in
-    // the middle of the buffer. "normal operation" is reading or
-    // writing to the end of the buffer. this happens e.g. when flushing.
-    if (s->bpos && s->size > s->bpos) {
-        memmove(s->buf, s->buf + s->bpos, s->size - s->bpos);
-    }
-    s->size -= s->bpos;
-    s->bpos = 0;
-}
-
-int ios_flush(ios_t *s)
-{
-    if (ndirty == 0 || s->bm == bm_mem || s->buf == NULL)
-        return 0;
-    if (s->fd == -1)
-        return -1;
-
-    int partialb=0;
-    if (s->bitpos > 0 && s->ndirty==s->bpos+1) {
-        // flushing partial byte
-        partialb=1;
-    }
-
-    size_t nw, ntowrite=s->ndirty;
-    int err = _os_write(s->fd, s->buf, ntowrite, &nw);
-    // todo: try recovering from some kinds of errors (e.g. retry)
-    if (partialb) {
-        // skip back 1, since we might have to write this byte again
-        // if more bits in it are changed
-        if (lseek(s->fd, -1, SEEK_CUR) == (off_t)-1) {
-            // uhoh. can't write the "rest" of this byte. move to next
-            // byte instead.
-            s->bpos++;
-            s->bitpos = 0;
-        }
-    }
-
-    _discard_partial_buffer(s);
-    s->ndirty = 0;
-
-    if (err)
-        return err;
-    if (nw < ntowrite)
-        return -1;
-    return 0;
-}
-
-void ios_close(ios_t *s)
-{
-    ios_flush(s);
-    if (s->fd != -1 && s->ownfd)
-        close(s->fd);
-    s->fd = -1;
-}
-
-char *ios_takebuf(ios_t *s, size_t *psize)
-{
-    char *buf;
-
-    ios_flush(s);
-
-    if (s->buf == &s->local[0]) {
-        buf = malloc(s->size+1);
-        if (buf == NULL)
-            return NULL;
-        if (s->size)
-            memcpy(buf, s->buf, s->size);
-        buf[s->size] = '\0';
-    }
-    else {
-        buf = s->buf;
-    }
-
-    *psize = s->size+1;  // buffer is actually 1 bigger for terminating NUL
-
-    /* empty stream and reinitialize */
-    if (s->bm == bm_mem || s->bm == bm_none) {
-        s->buf = &s->local[0];
-        s->maxsize = IOS_INLSIZE;
-    }
-    else {
-        s->buf = NULL;
-        _buf_realloc(s, IOS_BUFSIZE);
-    }
-    s->size = s->bpos = 0;
-    s->bitpos = 0;
-
-    return buf;
-}
-
-int ios_setbuf(ios_t *s, char *buf, size_t size, int own)
-{
-    ios_flush(s);
-    size_t nvalid=0;
-
-    nvalid = s->size;
-    if (s->size == s->bpos && s->bitpos>0)
-        nvalid++;
-    if (size < nvalid)
-        nvalid = size;
-    memcpy(buf, s->buf, nvalid);
-    if (s->bpos > nvalid) {
-        // truncated
-        s->bpos = nvalid;
-        s->bitpos = 0;
-    }
-    s->size = nvalid;
-
-    if (s->buf!=NULL && s->ownbuf && s->buf!=&s->local[0])
-        free(s->buf);
-    s->buf = buf;
-    s->maxsize = size;
-    s->ownbuf = own;
-    return 0;
-}
-
-int ios_bufmode(ios_t *s, bufmode_t mode)
-{
-    // no fd; can only do mem-only buffering
-    if (s->fd == -1 && mode != bm_mem)
-        return -1;
-    s->bm = mode;
-    return 0;
-}
-
-void ios_bswap(ios_t *s, int bswap)
-{
-    s->byteswap = !!bswap;
-}
-
-int ios_copy(ios_t *to, ios_t *from, size_t nbytes, bool_t all)
-{
-}
-
-
-/* stream object initializers. we do no allocation. */
-
-ios_t *ios_file(ios_t *s, char *fname, int create, int rewrite)
-{
-}
-
-ios_t *ios_mem(ios_t *s, size_t initsize)
-{
-}
-
-ios_t *ios_fd(ios_t *s, long fd)
-{
-}
-
-
-/* higher level interface */
-
-int ios_putbit(ios_t *s, int bit)
-{
-    byte_t mask = 1<<s->bitpos;
-
-    if (_ios_setstate(s, iost_wr))
-        return 0;
-
-    if (!s->dirty) {
-        // haven't written any bits yet
-        // if stenciling is turned on, the buffer is already full and
-        // we don't need to do anything
-        if (s->rereadable && !s->stenciled) {
-            // fill buffer if we can
-        }
-    }
-
-    if (bit)
-        s->buf[s->bpos] |= mask;
-    else
-        s->buf[s->bpos] &= ~mask;
-    s->dirty = 1;
-
-    s->bitpos++;
-    if (s->bitpos > 7) {
-        s->bitpos = 0;
-        s->bpos++;
-        s->tally++;
-    }
-    return 1;
-}
-
-int ios_getbit(ios_t *s, int *pbit)
-{
-    byte_t mask = 1<<s->bitpos;
-
-    if (_ios_setstate(s, iost_rd))
-        return 0;
-
-    *pbit = (s->buf[s->bpos] & mask) ? 1 : 0;
-    s->bitpos++;
-    if (s->bitpos > 7) {
-        s->bitpos = 0;
-        s->bpos++;
-        s->tally++;
-    }
-    return 1;
-}
--- a/llt/attic/ios.h.old
+++ /dev/null
@@ -1,198 +1,0 @@
-#ifndef __IOS_H_
-#define __IOS_H_
-
-// this flag controls when data actually moves out to the underlying I/O
-// channel. memory streams are a special case of this where the data
-// never moves out.
-typedef enum { bm_none, bm_line, bm_block, bm_mem } bufmode_t;
-
-typedef enum { iost_none, iost_rd, iost_wr } iostate_t;
-
-#define IOS_INLSIZE 54
-#define IOS_BUFSIZE 4095
-
-typedef struct {
-    bufmode_t bm;
-
-    // the state only indicates where the underlying file position is relative
-    // to the buffer. reading: at the end. writing: at the beginning.
-    // in general, you can do any operation in any state.
-    iostate_t state;
-
-    char *buf;        // start of buffer
-    size_t maxsize;   // space allocated to buffer
-    size_t size;      // length of valid data in buf, >=ndirty
-    size_t bpos;      // current position in buffer
-    size_t ndirty;    // # bytes at &buf[0] that need to be written
-
-    // this is a public field that keeps a running count of bytes
-    // read or written. you can freely use and change it. this is
-    // intended for keeping track of relative positions in streams
-    // that don't have absolute positions (like sockets).
-    size_t tally;
-
-    // pointer-size integer to support platforms where it might have
-    // to be a pointer
-    long fd;
-
-    byte_t bitpos;
-    //unsigned char bitdirty:1;      // bit buffer needs to be written
-    unsigned char byteswap:1;
-    //unsigned char readonly:1;
-    unsigned char ownbuf:1;
-    unsigned char ownfd:1;
-
-    // this means you can read, seek back, then read the same data
-    // again any number of times. usually only true for files and strings.
-    unsigned char rereadable:1;
-
-    // this enables "stenciled writes". you can alternately write and
-    // seek without flushing in between. this performs read-before-write
-    // to populate the buffer, so "rereadable" capability is required.
-    // this is off by default, except for bit I/O if rereadable is true.
-    unsigned char stenciled:1;
-
-    // request durable writes (fsync)
-    // unsigned char durable:1;
-
-    // todo: mutex
-    char local[IOS_INLSIZE];
-} ios_t;
-
-/* low-level interface functions */
-size_t ios_read(ios_t *s, char *dest, size_t n);
-size_t ios_write(ios_t *s, char *data, size_t n);
-off_t ios_seek(ios_t *s, off_t pos);   // absolute seek
-off_t ios_seek_end(ios_t *s);
-off_t ios_skip(ios_t *s, off_t offs);  // relative seek
-off_t ios_pos(ios_t *s);  // get current position
-size_t ios_trunc(ios_t *s, size_t size);
-int ios_eof(ios_t *s);
-int ios_flush(ios_t *s);
-void ios_close(ios_t *s);
-char *ios_takebuf(ios_t *s, size_t *psize);  // release buffer to caller
-// set buffer space to use
-int ios_setbuf(ios_t *s, char *buf, size_t size, int own);
-int ios_bufmode(ios_t *s, bufmode_t mode);
-void ios_bswap(ios_t *s, int bswap);
-int ios_copy(ios_t *to, ios_t *from, size_t nbytes, bool_t all);
-//void ios_lock(ios_t *s);
-//int ios_trylock(ios_t *s);
-//int ios_unlock(ios_t *s);
-
-/* stream creation */
-ios_t *ios_file(ios_t *s, char *fname, int create, int rewrite);
-ios_t *ios_mem(ios_t *s, size_t initsize);
-ios_t *ios_fd(ios_t *s, long fd);
-// todo: ios_socket
-
-/* high-level functions - output */
-int ios_putnum(ios_t *s, char *data, uint32_t type);
-int ios_putint(ios_t *s, int n);
-int ios_pututf8(ios_t *s, uint32_t wc);
-int ios_putstringz(ios_t *s, char *str, bool_t do_write_nulterm);
-/* single-bit I/O - even works for mixed reads and writes.
-   mixing bit-level I/O with normal byte stream I/O has undefined effects and
-   will almost certainly destroy your file. */
-int ios_putbit(ios_t *s, int bit);
-int ios_printf(ios_t *s, char *format, ...);
-
-/* high-level stream functions - input */
-int ios_getnum(ios_t *s, char *data, uint32_t type);
-int ios_getutf8(ios_t *s, uint32_t *pwc);
-int ios_ungetutf8(ios_t *s, uint32_t wc);
-int ios_getstringz(ios_t *dest, ios_t *src);
-int ios_getstringn(ios_t *dest, ios_t *src, size_t nchars);
-int ios_readline(ios_t *dest, ios_t *s, char delim);
-int ios_getline(ios_t *s, char **pbuf, size_t *psz);
-int ios_getbit(ios_t *s, int *pbit);  // returns # of bits read (0 or 1)
-
-// seek by utf8 sequence increments
-int ios_nextutf8(ios_t *s);
-int ios_prevutf8(ios_t *s);
-
-/* stdio-style functions */
-#define IOS_EOF (-1)
-int ios_putc(ios_t *s, int c);
-wint_t ios_putwc(ios_t *s, wchar_t wc);
-int ios_getc(ios_t *s);
-wint_t ios_getwc(ios_t *s);
-int ios_ungetc(ios_t *s, int c);
-wint_t ios_ungetwc(ios_t *s, wint_t wc);
-#define ios_puts(s, str) ios_write(s, str, strlen(str))
-
-/*
-  With memory streams, mixed reads and writes are equivalent to performing
-  sequences of *p++, as either an lvalue or rvalue. File streams behave
-  similarly, but other streams might not support this. Using unbuffered
-  mode makes this more predictable.
-
-  Note on "unget" functions:
-  There are two kinds of functions here: those that operate on sized
-  blocks of bytes and those that operate on logical units like "character"
-  or "integer". The "unget" functions only work on logical units. There
-  is no "unget n bytes". You can only do an unget after a matching get.
-  However, data pushed back by an unget is available to all read operations.
-  The reason for this is that unget is defined in terms of its effect on
-  the underlying buffer (namely, it rebuffers data as if it had been
-  buffered but not read yet). IOS reserves the right to perform large block
-  operations directly, bypassing the buffer. In such a case data was
-  never buffered, so "rebuffering" has no meaning (i.e. there is no
-  correspondence between the buffer and the physical stream).
-
-  Single-bit I/O is able to write partial bytes ONLY IF the stream supports
-  seeking. Also, line buffering is not well-defined in the context of
-  single-bit I/O, so it might not do what you expect.
-
-  implementation notes:
-  in order to know where we are in a file, we must ensure the buffer
-  is only populated from the underlying stream starting with p==buf.
-
-  to switch from writing to reading: flush, set p=buf, cnt=0
-  to switch from reading to writing: seek backwards cnt bytes, p=buf, cnt=0
-
-  when writing: buf starts at curr. physical stream pos, p - buf is how
-  many bytes we've written logically. cnt==0
-
-  dirty == (bitpos>0 && state==iost_wr), EXCEPT right after switching from
-  reading to writing, where we might be in the middle of a byte without
-  having changed it.
-
-  to write a bit: if !dirty, read up to maxsize-(p-buf) into buffer, then
-  seek back by the same amount (undo it). write onto those bits. now set
-  the dirty bit. in this state, we can bit-read up to the end of the byte,
-  then formally switch to the read state using flush.
-
-  design points:
-  - data-source independence, including memory streams
-  - support 64-bit and large files
-  - efficient, low-latency buffering
-  - unget
-  - expose buffer to user, allow user-owned buffers
-  - allow direct I/O, don't always go through buffer
-  - buffer-internal seeking. makes seeking back 1-2 bytes very fast,
-    and makes it possible for sockets where it otherwise wouldn't be
-  - special support for utf8
-  - single-bit I/O
-  - tries to allow switching between reading and writing
-  - type-aware functions with byte-order swapping service
-  - position counter for meaningful data offsets with sockets
-
-  note:
-  the current code needs to be mostly rewritten. the design should be
-  as follows:
-
-  the buffer is a view of part of a file/stream. you can seek, read, and
-  write around in it as much as you like, as if it were just a string.
-
-  we keep track of the part of the buffer that's invalid (written to).
-  we remember whether the position of the underlying stream is aligned
-  with the end of the buffer (reading mode) or the beginning (writing mode).
-
-  based on this info, we might have to seek back before doing a flush.
-
-  as optimizations, we do no writing if the buffer isn't "dirty", and we
-  do no reading if the data will only be overwritten.
-*/
-
-#endif
--- a/llt/attic/streams.c
+++ /dev/null
@@ -1,1107 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <limits.h>
-
-#ifdef WIN32
-#include <malloc.h>
-#include <io.h>
-#include <fcntl.h>
-#include <errno.h>
-#define fileno _fileno
-#else
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#endif
-
-#include "dtypes.h"
-#include "utils.h"
-#include "utf8.h"
-#include "streams.h"
-
-unsigned int type_sizes[] = {
-    sizeof(int32_t), sizeof(int8_t), sizeof(int16_t),
-    sizeof(int32_t), sizeof(float),  sizeof(double), sizeof(int64_t), 0,
-
-    /* unsigned */
-    0, sizeof(u_int8_t), sizeof(u_int16_t),
-    sizeof(u_int32_t), 0, 0, sizeof(u_int64_t), 0,
-
-    /* complex */
-    2*sizeof(int32_t), 2*sizeof(int8_t), 2*sizeof(int16_t),
-    2*sizeof(int32_t), 2*sizeof(float),  2*sizeof(double), 2*sizeof(int64_t),0,
-
-    /* complex unsigned */
-    0, 2*sizeof(u_int8_t), 2*sizeof(u_int16_t),
-    2*sizeof(u_int32_t), 0, 0, 2*sizeof(u_int64_t), 0
-};
-
-bool_t valid_type(u_int32_t type)
-{
-    u_int32_t sz;
-
-    /* irrelevant bits set */
-    if (type & ~T_TYPEMASK)
-        return false;
-    sz = type & T_TYPESIZE;
-    if (sz > T_INT64)
-        return false;
-    if (type == T_CPLX|T_BOOL)
-        return false;
-    /* no unsigned float or complex unsigned */
-    if (type & T_UNSIGNED) {
-        if ((sz > T_INT && sz != T_INT64) || sz == T_BOOL || type&T_CPLX)
-            return false;
-    }
-    return true;
-}
-
-/* an important function: some stream routines need to call this at
-   various points to ensure proper coexistence with bitwise I/O */
-static void stream_bit_flush(stream_t *s)
-{
-    if (s->bitpos > 0) {
-        stream_write(s, &s->bitbuf, 1);
-        s->bitpos = 0;
-    }
-}
-
-void stream_flush(stream_t *s)
-{
-    stream_bit_flush(s);
-    s->funcs->flush(s);
-}
-
-void stream_free(stream_t *s)
-{
-    stream_flush(s);
-    s->funcs->free_func(s);
-}
-
-int stream_readfd(stream_t *s)
-{
-    if (is_filestream(s)) {
-        return fileno(s->fptr);
-    }
-    else if (is_pipestream(s)) {
-        return s->rd;
-    }
-    return -1;
-}
-
-int stream_writefd(stream_t *s)
-{
-    if (is_filestream(s)) {
-        return fileno(s->fptr);
-    }
-    else if (is_pipestream(s)) {
-        return s->wd;
-    }
-    return -1;
-}
-
-
-/* file stream */
-
-off_t fs_seek(struct _stream *s, off_t where)
-{
-    FILE *f = s->fptr;
-
-    stream_bit_flush(s);
-
-    if (fseek(f, where, SEEK_SET) == -1)
-        return -1;
-    s->pos = ftell(f);
-    return s->pos;
-}
-
-off_t fs_skip(struct _stream *s, off_t offs)
-{
-    FILE *f = s->fptr;
-
-    stream_bit_flush(s);
-
-    // a successful fseek always resets the end-of-file condition, even if
-    // the offset is zero. we change this so that moving by 0 bytes when you're
-    // at eof means you stay at eof.
-    if (offs == 0)
-        return s->pos;
-
-    if (fseek(f, offs, SEEK_CUR) == -1)
-        return -1;
-    s->pos += offs;
-    return s->pos;
-}
-
-off_t fs_seek_end(struct _stream *s)
-{
-    FILE *f = s->fptr;
-
-    stream_bit_flush(s);
-
-    if (fseek(f, 0, SEEK_END) == -1)
-        return -1;
-    s->pos = ftell(f);
-    return s->pos;
-}
-
-size_t fs_read(struct _stream *s, char *dest, size_t size)
-{
-    FILE *f = s->fptr;
-    size_t c;
-
-    c = fread(dest, 1, size, f); /* read single-byte entities */
-    s->pos += c;
-    return c;
-}
-
-size_t fs_write(struct _stream *s, char *data, size_t size)
-{
-    FILE *f = s->fptr;
-    size_t c;
-
-    c = fwrite(data, 1, size, f);
-    s->pos += c;
-    return c;
-}
-
-size_t fs_trunc(struct _stream *s, size_t size)
-{
-    FILE *f = s->fptr;
-
-#ifndef WIN32
-    if (ftruncate(fileno(f), s->pos) == -1)
-        return -1; // TODO this should be unsigned!
-#else
-    if (_chsize(_fileno(f), s->pos) == -1)
-        return -1;
-#endif
-    return s->pos;
-}
-
-void fs_flush(struct _stream *s)
-{
-    FILE *f = s->fptr;
-
-    (void)fflush(f);
-}
-
-bool_t fs_eof(struct _stream *s)
-{
-    return (bool_t)feof(s->fptr);
-}
-
-void free_fs_stream(stream_t *s)
-{
-    fclose(s->fptr);
-    free(s->name);
-}
-
-void stream_close(stream_t *s)
-{
-    /*
-    if (!is_filestream(s))
-        return;
-    */
-    stream_flush(s);
-    // so far file streams are not designed to exist in the closed state
-    //    fclose(s->fptr);
-}
-
-stream_interface_t fs_funcs =
-    {free_fs_stream, fs_seek, fs_seek_end, fs_skip,
-     fs_read, fs_write, fs_trunc, fs_eof, fs_flush};
-
-stream_t *filestream_new(stream_t *s,
-                         char *fName, bool_t create, bool_t rewrite)
-{
-    FILE *f;
-    size_t sz;
-
-    if (create) {
-        if (rewrite) {
-            f = fopen(fName, "w+b");
-        }
-        else {
-            f = fopen(fName, "a+b");
-            if (f)
-                fseek(f, 0, SEEK_SET);
-        }
-    }
-    else {
-        f = fopen(fName, "r+b");
-    }
-    if (f == NULL) {
-        /* try readonly */
-        f = fopen(fName, "rb");
-        if (f == NULL)
-            return NULL;
-    }
-
-    s->fptr = f;
-    s->name = strdup(fName);
-
-    s->funcs = &fs_funcs;
-
-    s->pos = 0;
-    s->bitpos = s->bitbuf = 0;
-    s->byteswap = false;
-    return s;
-}
-
-stream_t *stream_fromfile(stream_t *s, FILE *f, char *name)
-{
-    s->fptr = f;
-    s->name = strdup(name);
-
-    s->funcs = &fs_funcs;
-
-    s->pos = 0;
-    s->bitpos = s->bitbuf = 0;
-    s->byteswap = false;
-    return s;
-}
-
-/* memory stream */
-
-off_t ms_seek(struct _stream *s, off_t where)
-{
-    if ((size_t)where > s->size)
-        return -1;
-
-    stream_bit_flush(s);
-    s->pos = where;
-
-    return s->pos;
-}
-
-off_t ms_skip(struct _stream *s, off_t offs)
-{
-    if (s->pos+offs < 0 || s->pos+offs > s->size)
-        return -1;
-
-    stream_bit_flush(s);
-
-    s->pos += offs;
-    return s->pos;
-}
-
-off_t ms_seek_end(struct _stream *s)
-{
-    stream_bit_flush(s);
-    s->pos = s->size;
-    return s->pos;
-}
-
-size_t ms_read(struct _stream *s, char *dest, size_t size)
-{
-    size_t amt = size;
-
-    assert(s->pos <= s->size);
-
-    if (size == 0)
-        return 0;
-
-    if (s->size - s->pos < size)
-        amt = s->size - s->pos;
-
-    if (amt > 0) {
-        memcpy(dest, &s->data[s->pos], amt);
-    }
-
-    s->pos += amt;
-    return amt;
-}
-
-static char *ms_realloc(stream_t *s, size_t size)
-{
-    char *temp;
-
-    if (size <= s->maxsize)
-        return s->data;
-
-    /* UNOFFICIALLY, we put a '\0' at the end of every memory stream for
-       compatability with C library string functions, which are convenient.
-       You are not allowed to depend on this behavior; it may eventually
-       change.
-
-       We implement this by telling everybody that maxsize is one less than
-       the actual size of the buffer. They think the last byte is at index
-       maxsize-1, but it is actually at index maxsize.
-
-       data[s->size] and data[s->maxsize] are kept at '\0'. */
-
-    if (size <= N_STREAM_LOCAL-1) {
-        /* TO DO: if we want to allow shrinking, see if the buffer shrank
-           down to this size, in which case we need to copy. */
-        s->data = &s->local[0];
-        s->maxsize = N_STREAM_LOCAL-1;
-        s->data[s->maxsize] = '\0';
-        return s->data;
-    }
-    if (s->data == &s->local[0]) {
-        temp = malloc(size+1);
-        // TODO nullcheck
-        memcpy(temp, s->data, s->size);
-    }
-    else {
-        /* here we rely on the realloc() behavior of
-           doing a malloc() when passed a NULL pointer. */
-        temp = realloc(s->data, size+1);
-        if (temp == NULL)
-            return NULL;
-    }
-    s->data = temp;
-    s->maxsize = size;
-    s->data[s->maxsize] = '\0';
-    return s->data;
-}
-
-size_t ms_trunc(struct _stream *s, size_t size)
-{
-    if (size == s->size)
-        return size;
-
-    if (size < s->size) {
-        // TODO: if big shrink, release space
-        if (s->pos > size)
-            s->pos = size;
-    }
-    else {
-        if (ms_realloc(s, size) == NULL)
-            return s->size;
-    }
-
-    s->size = size;
-    s->data[size] = '\0';
-    return size;
-}
-
-size_t ms_write(struct _stream *s, char *data, size_t size)
-{
-    size_t amt;
-    size_t newsize;
-
-    if (size == 0)
-        return 0;
-
-    if (s->pos + size > s->size) {
-        if (s->pos + size > s->maxsize) {
-            /* TO DO: here you might want to add a mechanism for limiting
-               the growth of the stream. */
-            newsize = s->maxsize * 2;
-            while (s->pos + size > newsize)
-                newsize *= 2;
-            if (ms_realloc(s, newsize) == NULL) {
-                /* no more space; write as much as we can */
-                amt = s->maxsize - s->pos;
-                if (amt > 0) {
-                    memcpy(&s->data[s->pos], data, amt);
-                }
-                s->pos += amt;
-                s->size = s->maxsize;
-                /* in this case we've written up to the end of the buffer,
-                   so we know the next char is \0 since ms_realloc sets that
-                   up every time it allocates. */
-                return amt;
-            }
-        }
-        s->size = s->pos + size;
-
-        /* always valid since secretly we know the buffer is 1 bigger than
-           maxsize */
-        s->data[s->size] = '\0';
-    }
-    memcpy(&s->data[s->pos], data, size);
-    s->pos += size;
-
-    return size;
-}
-
-void ms_flush(struct _stream *s)
-{
-}
-
-bool_t ms_eof(struct _stream *s)
-{
-    assert(s->pos <= s->size);
-    return (bool_t)(s->pos == s->size);
-}
-
-void free_ms_stream(stream_t *s)
-{
-    if (s->data != NULL && s->data != &s->local[0])
-        free(s->data);
-}
-/*
-stream_t *memstream_copy(stream_t *s)
-{
-    stream_t *ns = memstream_new(s->size);
-
-    ms_write(ns, s->s, s->size);
-    stream_seek(ns, 0);
-    return ns;
-}
-*/
-stream_interface_t ms_funcs =
-    {free_ms_stream, ms_seek, ms_seek_end, ms_skip,
-     ms_read, ms_write, ms_trunc, ms_eof, ms_flush};
-
-stream_t *memstream_new(stream_t *s, size_t initsize)
-{
-    s->pos = 0;
-    s->size = 0;
-    s->data = &s->local[0];
-    s->maxsize = N_STREAM_LOCAL-1;
-    s->data[s->maxsize] = '\0';
-
-    if (ms_realloc(s, initsize) == NULL)
-        julia_outofmemory();
-
-    s->data[initsize] = '\0';
-    s->data[s->pos] = '\0';
-    s->size = initsize;
-
-    s->funcs = &ms_funcs;
-
-    s->bitpos = s->bitbuf = 0;
-    s->byteswap = false;
-
-    return s;
-}
-
-#if 0
-string_t *string_new(int len)
-{
-    string_t *str;
-
-    str = memstream_new(len);
-    str->len = len;
-
-    return str;
-}
-
-/* this function makes string streams from C strings (NUL-term) */
-string_t *string_fromc(char *s)
-{
-    string_t *str;
-    int len = strlen(s);
-
-    str = string_new(len);
-    stream_write(str, s, len);
-    stream_seek(str, 0);
-
-    return str;
-}
-#endif
-
-/* pipe */
-off_t ps_seek(struct _stream *s, off_t where)
-{
-    return -1;
-}
-
-size_t ps_read(struct _stream *s, char *dest, size_t size);
-
-off_t ps_skip(struct _stream *s, off_t offs)
-{
-    char buf[CHUNK_SIZE];
-    int rd = s->rd;
-    size_t c, amt;
-
-    if (offs < 0)
-        return -1;
-    while (offs > 0) {
-        amt = offs > CHUNK_SIZE ? CHUNK_SIZE : offs;
-        c = ps_read(s, buf, amt);
-        if (c < amt)
-            return 0;
-        offs -= c;
-    }
-    return 0;
-}
-
-off_t ps_seek_end(struct _stream *s)
-{
-    return -1;
-}
-
-size_t ps_read(struct _stream *s, char *dest, size_t size)
-{
-    if (ps_eof(s))
-        return 0;
-#ifdef WIN32
-    int c = _read(s->rd, dest, size);
-#else
-    ssize_t c = read(s->rd, dest, size);
-#endif
-    if (c < 0)
-        return 0;
-    return (size_t)c;
-}
-
-size_t ps_write(struct _stream *s, char *data, size_t size)
-{
-#ifdef WIN32
-    int c = _write(s->wd, data, size);
-#else
-    ssize_t c = write(s->wd, data, size);
-#endif
-    if (c < 0)
-        return 0;
-    return c;
-}
-
-size_t ps_trunc(struct _stream *s, size_t size)
-{
-    return 0;
-}
-
-void ps_flush(struct _stream *s)
-{
-}
-
-bool_t ps_eof(struct _stream *s)
-{
-#ifndef WIN32
-    fd_set set;
-    struct timeval tv = {0, 0};
-
-    FD_ZERO(&set);
-    FD_SET(s->rd, &set);
-    return (select(s->rd+1, &set, NULL, NULL, &tv)==0);
-#else
-    return 0;
-#endif
-}
-
-void free_ps_stream(stream_t *s)
-{
-    close(s->rd);
-    close(s->wd);
-}
-
-stream_interface_t ps_funcs =
-    {free_ps_stream, ps_seek, ps_seek_end, ps_skip,
-     ps_read, ps_write, ps_trunc, ps_eof, ps_flush};
-
-stream_t *pipestream_new(stream_t *s, int flags)
-{
-    int fds[2];
-
-    s->funcs = &ps_funcs;
-
-#ifdef WIN32
-    _pipe(&fds[0], 32768, _O_BINARY | flags);
-#else
-    pipe(&fds[0]);
-#endif
-    s->rd = fds[0]; s->wd = fds[1];
-
-    s->byteswap = false;
-    s->bitpos = s->bitbuf = 0;
-    s->pos = 0;
-
-    return s;
-}
-
-
-/* high-level stream functions */
-
-/* type is a "T_" code as defined in streams.h */
-int stream_put_num(stream_t *stream, char *d, u_int32_t type)
-{
-    int c, sz, i;
-
-    assert(valid_type(type));
-    sz = type_sizes[type];
-
-    if (!stream->byteswap) {
-        c = stream_write(stream, d, sz);
-    }
-    else if (sz >= 4) {
-        char temp[32];
-        if (type & T_CPLX) {
-            bswap_to(temp,      (byte_t*)d,      sz/2);
-            bswap_to(temp+sz/2, (byte_t*)d+sz/2, sz/2);
-        }
-        else {
-            bswap_to(temp, (byte_t*)d, sz);
-        }
-        c = stream_write(stream, temp, sz);
-    }
-    else {
-        assert(sz == 2 || sz == 1);
-        if (type & T_CPLX) {
-            c = stream_write(stream, &d[0], 2);
-            /*
-            for(i=sz/2-1; i >= 0; i--) {
-                c += stream_write(stream, &d[i], 1);
-            }
-            for(i=sz-1; i >= sz/2; i--) {
-                c += stream_write(stream, &d[i], 1);
-            }
-            */
-        }
-        else {
-            c = 0;
-            if (sz == 2)
-                c += stream_write(stream, &d[1], 1);
-            c += stream_write(stream, &d[0], 1);
-        }
-    }
-
-    return c;
-}
-
-int stream_get_num(stream_t *s, char *data, u_int32_t type)
-{
-    int c, sz;
-
-    assert(valid_type(type));
-    sz = type_sizes[type];
-
-    c = stream_read(s, data, sz);
-
-    if (s->byteswap && c == sz) {
-        if (type & T_CPLX) {
-            bswap((byte_t*)data, sz/2);
-            bswap((byte_t*)data+sz/2, sz/2);
-        }
-        else {
-            bswap((byte_t*)data, sz);
-        }
-    }
-    if (c < sz)
-        return -1;
-    return c;
-}
-
-int stream_put_int(stream_t *s, int n)
-{
-    return stream_put_num(s, (char*)&n, T_INT);
-}
-
-int stream_put_char(stream_t *s, u_int32_t wc)
-{
-    char buf[8];
-    int amt;
-
-    amt = u8_wc_toutf8(buf, wc);
-    return stream_write(s, buf, amt);
-}
-
-int stream_put_stringz(stream_t *s, char *str, bool_t nulterm)
-{
-    int c, l = strlen(str);
-
-    c = stream_write(s, str, l);
-    if (nulterm)
-        c += stream_write(s, &str[l], 1);
-    return c;
-}
-
-int stream_get_char(stream_t *s, u_int32_t *pwc)
-{
-    char buf[8];
-    int amt;
-    unsigned int i;
-
-    amt = stream_read(s, buf, 1);
-    if (amt == 0)
-        return 0;
-    amt = u8_seqlen(buf) - 1;  // find out how many more bytes in this seq
-    if (amt) {
-        stream_read(s, &buf[1], amt);
-    }
-    amt++;
-    buf[amt] = '\0';
-    i=0;
-    *pwc = u8_nextmemchar(buf, &i);
-    return i;
-}
-
-int stream_nextchar(stream_t *s)
-{
-    u_int32_t wc;
-
-    if (is_memstream(s)) {
-        if (stream_eof(s))
-            return -1;
-        stream_bit_flush(s);
-        s->pos++;
-        while (!stream_eof(s) && !isutf(s->s[s->pos]))
-            s->pos++;
-        return s->pos;
-    }
-
-    if (stream_get_char(s, &wc) == 0)
-        return -1;
-    return s->pos;
-}
-
-int stream_prevchar(stream_t *s)
-{
-    char c;
-
-    if (is_memstream(s)) {
-        if (s->pos == 0)
-            return -1;
-        stream_bit_flush(s);
-        s->pos--;
-        while (s->pos > 0 && !isutf(s->s[s->pos]))
-            s->pos--;
-        return s->pos;
-    }
-
-    do {
-        if (stream_skip(s, -1) == -1)
-            return -1;
-        stream_read(s, &c, 1);
-        stream_skip(s, -1);
-    } while(!isutf(c));
-    return s->pos;
-}
-
-void stream_put_bit(stream_t *s, int bit)
-{
-    byte_t mask = 0x1;
-
-    if (s->bitpos == 0) {
-        if (!stream_read(s, &s->bitbuf, 1)) {
-            s->bitbuf = 0;
-        }
-        else {
-            stream_skip(s, -1);
-        }
-    }
-
-    mask <<= s->bitpos;
-    if (bit)
-        s->bitbuf |= mask;
-    else
-        s->bitbuf &= ~mask;
-    s->dirty = 1;
-
-    s->bitpos++;
-    if (s->bitpos > 7) {
-        s->bitpos = 0;
-        stream_write(s, &s->bitbuf, 1);
-    }
-}
-
-int stream_get_bit(stream_t *s, int *pbit)
-{
-    byte_t mask = 0x1;
-
-    if (s->bitpos == 0) {
-        if (!stream_read(s, &s->bitbuf, 1)) {
-            return 0;
-        }
-        else {
-            stream_skip(s, -1);
-        }
-        s->dirty = 0;
-    }
-
-    mask <<= s->bitpos;
-    *pbit = (s->bitbuf & mask) ? 1 : 0;
-
-    s->bitpos++;
-
-    if (s->bitpos > 7) {
-        s->bitpos = 0;
-        if (s->dirty) {
-            stream_write(s, &s->bitbuf, 1);
-        }
-        else {
-            stream_skip(s, 1);
-        }
-    }
-    return 1;
-}
-
-/* warning: DO NOT write a trivial wrapper for this function; it allows
-   easily crashing the interpreter using unfriendly format strings.
-
-   also, this function is designed to print small things like messages. it
-   cannot print arbitrarily large data. to do that, use stream_write,
-   or repeated calls to this function.
-
-   TODO: this doesn't handle UTF-8 properly:
-
-printf("%*s|\n%*s|\n", -4, "X", -4, "a")
-printf("%-4s|\n%-4s|\n", "X", "a")
-X  |
-a   |
-
-Where X is a 2-byte character.
-*/
-int stream_printf(stream_t *s, char *format, ...)
-{
-    int c;
-    va_list args;
-    char buf[512];
-
-    va_start(args, format);
-    c = vsnprintf(buf, sizeof(buf), format, args);
-    va_end(args);
-
-    if (c < 0)
-        return 0;
-
-    if ((unsigned)c > sizeof(buf))
-        c = sizeof(buf);
-
-    return stream_write(s, buf, c);
-}
-
-char *stream_take_buffer(stream_t *s, size_t *size)
-{
-    char *buf;
-
-    if (!is_memstream(s) || s->data == NULL)
-        return NULL;
-
-    stream_flush(s);
-
-    if (s->data == &s->local[0]) {
-        buf = malloc(s->size+1);
-        if (buf == NULL)
-            return NULL;
-        memcpy(buf, s->data, s->size+1);
-        buf[s->size] = '\0';
-    }
-    else {
-        buf = s->data;
-    }
-
-    *size = s->size+1; /* buffer is actually 1 bigger for terminating NUL */
-
-    /* empty stream and reinitialize */
-    s->data = &s->local[0];
-    s->maxsize = N_STREAM_LOCAL-1;
-    s->data[s->maxsize] = '\0';
-    stream_trunc(s, 0);
-
-    return buf;
-}
-
-/* Chunk size for reading lines: if too small, then we make too many low-level
-   calls. if too large, then we waste time reading bytes beyond the end of the
-   current line. this is effectively a guess as to how big a line is.
-   this value should be < N_STREAM_LOCAL, allowing at least some lines to
-   fit without extra allocation. */
-#define LINE_CHUNK_SIZE (N_STREAM_LOCAL-1)
-
-int stream_readline(stream_t *dest, stream_t *s, char delim)
-{
-    char chunk[LINE_CHUNK_SIZE];
-    int i, cnt, total=0;
-
-    if (stream_eof(s))
-        return 0;
-
-    do {
-        cnt = stream_read(s, chunk, LINE_CHUNK_SIZE);
-        for(i=0; i < cnt; i++) {
-            if (chunk[i] == delim)
-                break;
-        }
-        if (i < cnt) {
-            total += stream_write(dest, chunk, i+1);
-            stream_skip(s, -(cnt-(i+1)));
-            break;
-        }
-        total += stream_write(dest, chunk, cnt);
-    } while (!stream_eof(s));
-
-    return total;
-}
-
-/* extract one line of text from a stream, into a memory buffer.
-   a pointer to the buffer is returned in *pbuf, the size of the buffer
-   in *psz, and the number of characters in the line (including newline) is
-   returned. the line may contain NULs, but there will also be a NUL
-   terminator as the last character in the buffer.
-
-   This routine's behavior is not exactly the same as GNU getline. In
-   particular, it always allocates a buffer.
-*/
-int stream_getline(stream_t *s, char **pbuf, size_t *psz)
-{
-    stream_t buf;
-
-    memstream_new(&buf, 0);
-
-    stream_readline(&buf, s, '\n');
-
-    *pbuf = stream_take_buffer(&buf, psz);
-
-    return *psz-1;
-}
-
-int stream_get_stringz(stream_t *dest, stream_t *src)
-{
-    return stream_readline(dest, src, '\0');
-}
-
-/* get n UTF-8 characters */
-int stream_get_stringn(stream_t *dest, stream_t *src, size_t c)
-{
-    u_int32_t wc;
-    size_t cnt=0;
-
-    while (c > 0) {
-        if (stream_get_char(src, &wc) == 0 ||
-            stream_put_char(dest, wc) == 0)
-            break;
-        c--;
-        cnt++;
-    }
-    return cnt;
-}
-
-/* TODO: change API to allow passing a heap-allocated page-aligned
-   chunk to reuse on each copy. if it's NULL we alloc our own. */
-int stream_copy(stream_t *to, stream_t *from, size_t nbytes, bool_t all)
-{
-    int c=0, cnt, wc, rdc;
-    char buf[CHUNK_SIZE];
-    int remain = all ? CHUNK_SIZE : nbytes;
-
-    if (is_memstream(to)) {
-        // avoid extra copy, read directly into memstream
-        while (!stream_eof(from)) {
-            if (all) {
-                rdc = CHUNK_SIZE;
-            }
-            else {
-                /* if !all, only 1 call to stream_read needed */
-                rdc = nbytes;
-            }
-
-            if (ms_realloc(to, to->pos + rdc) == NULL) {
-                rdc = to->maxsize - to->pos;
-                if (rdc == 0)
-                    break;
-            }
-            cnt = stream_read(from, &to->s[to->pos], rdc);
-            wc = cnt;
-            to->pos += wc;
-            if (to->pos > to->size) {
-                to->size = to->pos;
-                to->s[to->size] = '\0';
-            }
-            c += wc;
-
-            if (!all)
-                remain -= wc;
-            if (wc < rdc || remain == 0)
-                break;
-        }
-    }
-    else if (is_memstream(from)) {
-        while (1) {
-            if (all) {
-                rdc = CHUNK_SIZE;
-            }
-            else {
-                /* if !all, only 1 call to stream_read needed */
-                rdc = nbytes;
-            }
-            // check for source out of data
-            if (from->size - from->pos < rdc) {
-                remain = rdc = from->size - from->pos;
-            }
-            cnt = stream_write(to, &from->s[from->pos], rdc);
-            wc = cnt;
-            from->pos += wc;
-            c += wc;
-            if (!all)
-                remain -= wc;
-            if (wc < rdc || remain == 0)
-                break;
-        }
-    }
-    else {
-        while (!stream_eof(from)) {
-            rdc = remain>CHUNK_SIZE ? CHUNK_SIZE : remain;
-
-            cnt = stream_read(from, buf, rdc);
-            wc = stream_write(to, buf, cnt);
-            c += wc;
-
-            if (!all)
-                remain -= wc;
-            if (wc < rdc || remain == 0)
-                break;
-        }
-    }
-    return c;
-}
-
-
-/* serialization functions */
-
-/* nbytes is either 4 or 8 */
-size_t stream_get_offset(stream_t *s, off_t *po, int nbytes)
-{
-    size_t c;
-    int64_t off64;
-    int32_t off32;
-
-    if (nbytes == 4) {
-        c = stream_read(s, (char*)&off32, nbytes);
-        if (c < nbytes)
-            return c;
-        if (s->byteswap)
-            off32 = bswap_32(off32);
-        /* OK on either system since off_t is >= off32 in size */
-        *po = (off_t)off32;
-    }
-    else {
-        c = stream_read(s, (char*)&off64, nbytes);
-        if (c < nbytes)
-            return c;
-        if (s->byteswap)
-            off64 = bswap_64(off64);
-        if (sizeof(off_t) == 8) {
-            *po = (off_t)off64;
-        }
-        else {
-            if (off64 <= INT_MAX && off64 >= INT_MIN) {
-                // downcast safe
-                *po = (off_t)off64;
-            }
-            else {
-                cerror("I/O error: 64-bit offset truncated on input.\n");
-            }
-        }
-    }
-
-    return c;
-}
-
-size_t stream_put_offset(stream_t *s, off_t o, int nbytes)
-{
-    int64_t off64;
-    int32_t off32;
-
-    if (nbytes == 4) {
-        if (sizeof(off_t) == 8 && (o > INT_MAX || o < INT_MIN)) {
-            cerror("I/O error: 64-bit offset truncated on output.\n");
-        }
-        off32 = (int32_t)o;
-        if (s->byteswap)
-            off32 = bswap_32(off32);
-        return stream_write(s, (char*)&off32, 4);
-    }
-    off64 = (int64_t)o;
-    if (s->byteswap)
-        off64 = bswap_64(off64);
-    return stream_write(s, (char*)&off64, 8);
-}
--- a/llt/attic/streams.h
+++ /dev/null
@@ -1,213 +1,0 @@
-#ifndef __STREAMS_H_
-#define __STREAMS_H_
-
-struct _stream;
-
-// numeric type codes
-#define T_BOOL   0x000
-#define T_BYTE   0x001
-#define T_SHORT  0x002
-#define T_INT    0x003
-#define T_FLOAT  0x004
-#define T_DOUBLE 0x005
-#define T_INT64   0x006
-//#define T_LDOUBLE 0x007
-#define T_UNSIGNED 0x008
-#define T_CPLX     0x010
-
-#define T_TYPEMASK 0x1f  /* bits related to numeric type */
-#define T_TYPESIZE 0x07  /* bits related to type size */
-
-#define is_type(a, t) (((a) & T_TYPESIZE) == (t))
-// type_bitseq tells whether 2 types are bit-representation compatible
-#define type_bitseq(a, b) (((a) & ~T_UNSIGNED) == ((b) & ~T_UNSIGNED))
-
-extern unsigned int type_sizes[];
-
-typedef struct {
-    void (*free_func)(struct _stream *s);
-    /* these return -1 on error, or new position if successful */
-    /* set absolute position */
-    off_t (*seek)(struct _stream *s, off_t where);
-    /* seek to end (past last byte) */
-    off_t (*seek_end)(struct _stream *s);
-    /* move relative to current position */
-    off_t (*skip)(struct _stream *s, off_t offs);
-
-    /* these return # of bytes read/written, 0 on error */
-    size_t (*read)(struct _stream *s, char *dest, size_t size);
-    size_t (*write)(struct _stream *s, char *data, size_t size);
-
-    /* truncate a stream to the given length */
-    size_t (*trunc)(struct _stream *s, size_t size);
-
-    /* no data left? */
-    bool_t (*eof)(struct _stream *s);
-
-    /* sync bit buffer, and sync to hardware if applicable */
-    void (*flush)(struct _stream *s);
-    /* could add fsync() call for durable writes */
-} stream_interface_t;
-
-extern stream_interface_t fs_funcs;
-extern stream_interface_t ms_funcs;
-extern stream_interface_t ps_funcs;
-
-#define is_memstream(s)  (((stream_t*)s)->funcs==&ms_funcs)
-#define is_filestream(s) (((stream_t*)s)->funcs==&fs_funcs)
-#define is_pipestream(s) (((stream_t*)s)->funcs==&ps_funcs)
-
-/* general i/o chunk size */
-#define CHUNK_SIZE 4096
-
-/* this should be a multiple of 4; otherwise the struct gets padded to
-   the next multiple of 4 anyway, wasting space */
-#define N_STREAM_LOCAL 40
-
-typedef struct _stream {
-    /* unfortunately, it seems that pos needs to be a signed type to be
-       compatible with OS functions. */
-    off_t pos;
-    byte_t bitpos;     /* offset within a byte, for writing individual bits */
-    byte_t bitbuf;     /* a copy of the byte at the current stream position */
-    char ungotc;
-    struct {
-        /* does bit buffer need to be written? */
-        unsigned char dirty:1;
-        unsigned char byteswap:1;
-        unsigned char readonly:1;
-        unsigned char ungot:1;
-    };
-
-    stream_interface_t *funcs;
-
-    /* stream-specific data */
-    union {
-        char *name;
-        size_t maxsize;
-        int rd; // pipe read descriptor
-    };
-    union {
-        FILE *fptr;
-        char *data;
-        char *s;
-        int wd; // pipe write descriptor
-    };
-    union {
-        /* this is always a size in BYTES */
-        size_t size;
-        size_t len;
-    };
-    char local[N_STREAM_LOCAL];
-} stream_t;
-
-#include <stdio.h>
-
-stream_t *filestream_new(stream_t *s, char *fName,
-                         bool_t create, bool_t rewrite);
-stream_t *memstream_new(stream_t *s, size_t initsize);
-stream_t *pipestream_new(stream_t *s, int flags);
-stream_t *stream_fromfile(stream_t *s, FILE *f, char *name);
-//string_t *string_new(int len);
-//string_t *string_fromc(char *s);
-stream_t *memstream_copy(stream_t *s);
-void stream_free(stream_t *s);
-void stream_flush(stream_t *s);
-
-
-/* high level stream functions */
-
-/* 'all' means copy to end of stream */
-int stream_copy(stream_t *to, stream_t *from, size_t nbytes, bool_t all);
-
-int stream_put_num(stream_t *s, char *data, u_int32_t type);
-int stream_put_int(stream_t *s, int n);
-int stream_put_char(stream_t *s, u_int32_t wc);
-int stream_put_stringz(stream_t *s, char *str, bool_t nulterm);
-
-/* single-bit I/O - even works for mixed reads and writes.
-   mixing bit-level I/O with normal byte stream I/O has undefined effects and
-   will almost certainly destroy your file. however, it is safe to switch
-   between bit and byte I/O if you call stream_flush in between. */
-void stream_put_bit(stream_t *s, int bit);
-
-/* warning: this uses a fixed-size buffer. it is intended only for printing
-   normal things like "a= %d". if you might be printing a large buffer, you
-   should use stream i/o functions directly. */
-int stream_printf(stream_t *s, char *format, ...);
-
-
-/* high level stream functions - input */
-
-int stream_get_num(stream_t *s, char *data, u_int32_t type);
-int stream_get_char(stream_t *s, u_int32_t *pwc);
-int stream_get_stringz(stream_t *dest, stream_t *src);
-int stream_get_stringn(stream_t *dest, stream_t *src, size_t c);
-int stream_readline(stream_t *dest, stream_t *s, char delim);
-int stream_getline(stream_t *s, char **pbuf, size_t *psz);
-/* returns # of bits read (0 or 1) */
-int stream_get_bit(stream_t *s, int *pbit);
-
-int stream_nextchar(stream_t *s);
-int stream_prevchar(stream_t *s);
-
-void stream_close(stream_t *s);
-
-/* TODO */
-// stream_fgetc
-// stream_ungetc
-
-/* get underlying file descriptors, -1 if none */
-int stream_readfd(stream_t *s);
-int stream_writefd(stream_t *s);
-
-/*
-  low level stream functions
-
-  Streams are intended to provide a uniform function interface to various
-  kinds of byte streams.
-
-  The eight low-level stream functions (below) are intended to be light weight.
-  It must be easy to implement reasonably efficient higher-level stream
-  functions, therefore any complexity required to make (for example) single
-  byte reads and writes efficient must be implemented by the stream.
-
-  Note that you can implement file streams using fread(), fwrite(), etc.
-  because buffering is already implemented in every standard C library. These
-  calls do not make system calls in general, and are perfectly fine to use.
-*/
-
-#define stream_seek(s, w)      (s)->funcs->seek(s, w)
-#define stream_seek_end(s)     (s)->funcs->seek_end(s)
-#define stream_skip(s, o)      (s)->funcs->skip(s, o)
-#define stream_read(s, d, sz)  (s)->funcs->read(s, (char*)d, sz)
-#define stream_write(s, d, sz) (s)->funcs->write(s, (char*)d, sz)
-#define stream_trunc(s, sz)    (s)->funcs->trunc(s, sz)
-#define stream_eof(s)          (s)->funcs->eof(s)
-
-
-STATIC_INLINE size_t stream_put_byte(stream_t *s, byte_t b)
-{
-    return stream_write(s, (char*)&b, 1);
-}
-
-STATIC_INLINE size_t stream_get_byte(stream_t *s, byte_t *pb)
-{
-    return stream_read(s, (char*)pb, 1);
-}
-
-#define stream_puts(s, str) stream_write(s, str, strlen(str))
-
-/*
-  stream_take_buffer
-
-  This lets you get the data of a stream without having to copy it. In order
-  not to either lose the buffer or free it twice, this operation effectively
-  empties the stream. In other words, size goes to 0, data becomes NULL.
-  Whoever called the function takes full responsibility for the buffer.
-  You must free it eventually.
-  "size" gets set to the size of the data in the buffer.
-*/
-char *stream_take_buffer(stream_t *s, size_t *size);
-
-#endif
--- a/llt/attic/trash.c
+++ /dev/null
@@ -1,68 +1,0 @@
-/* moving data in small power-of-2 sized units */
-void copy_el(char *dest, char *src, size_t sz)
-{
-    switch (sz) {
-    case 16:
-        *(int64_t*)&dest[0] = *(int64_t*)&src[0];
-        *(int64_t*)&dest[8] = *(int64_t*)&src[8];
-        break;
-    case 8: *(int64_t*)dest = *(int64_t*)src; break;
-    case 4: *(int32_t*)dest = *(int32_t*)src; break;
-    case 2: *(int16_t*)dest = *(int16_t*)src; break;
-    case 1: *dest = *src; break;
-    }
-}
-
-void swap_el(char *a, char *b, size_t sz)
-{
-    int64_t i64;
-    int32_t i32;
-    int16_t i16;
-    int8_t i8;
-    switch (sz) {
-    case 16:
-        i64 = *(int64_t*)&a[0];
-        *(int64_t*)&a[0] = *(int64_t*)&b[0];
-        *(int64_t*)&b[0] = i64;
-        i64 = *(int64_t*)&a[8];
-        *(int64_t*)&a[8] = *(int64_t*)&b[8];
-        *(int64_t*)&b[8] = i64;
-        break;
-    case 8:
-        i64 = *(int64_t*)a;
-        *(int64_t*)a = *(int64_t*)b;
-        *(int64_t*)b = i64;
-        break;
-    case 4:
-        i32 = *(int32_t*)a;
-        *(int32_t*)a = *(int32_t*)b;
-        *(int32_t*)b = i32;
-        break;
-    case 2:
-        i16 = *(int16_t*)a;
-        *(int16_t*)a = *(int16_t*)b;
-        *(int16_t*)b = i16;
-        break;
-    case 1:
-        i8 = *a;
-        *a = *b;
-        *b = i8;
-        break;
-    }
-}
-
-void neg_any(void *dest, void *a, numerictype_t tag)
-{
-    switch (tag) {
-    case T_INT8:   *(int8_t  *)dest = -*(int8_t  *)a; break;
-    case T_UINT8:  *(uint8_t *)dest = -*(uint8_t *)a; break;
-    case T_INT16:  *(int16_t *)dest = -*(int16_t *)a; break;
-    case T_UINT16: *(uint16_t*)dest = -*(uint16_t*)a; break;
-    case T_INT32:  *(int32_t *)dest = -*(int32_t *)a; break;
-    case T_UINT32: *(uint32_t*)dest = -*(uint32_t*)a; break;
-    case T_INT64:  *(int64_t *)dest = -*(int64_t *)a; break;
-    case T_UINT64: *(uint64_t*)dest = -*(uint64_t*)a; break;
-    case T_FLOAT:  *(float   *)dest = -*(float   *)a; break;
-    case T_DOUBLE: *(double  *)dest = -*(double  *)a; break;
-    }
-}
--- a/llt/scrap
+++ /dev/null
@@ -1,176 +1,0 @@
-/* null stream */
-off_t null_seek(struct _stream *s, off_t where)
-{
-    return -1;
-}
-
-off_t null_skip(struct _stream *s, off_t offs)
-{
-    return 0;
-}
-
-off_t null_seek_end(struct _stream *s)
-{
-    return -1;
-}
-
-size_t null_read(struct _stream *s, char *dest, size_t size)
-{
-    return 0;
-}
-
-size_t null_write(struct _stream *s, char *data, size_t size)
-{
-    return 0;
-}
-
-size_t null_trunc(struct _stream *s, size_t size)
-{
-    return 0;
-}
-
-void null_flush(struct _stream *s)
-{
-}
-
-bool_t null_eof(struct _stream *s)
-{
-    return true;
-}
-
-void free_null_stream(stream_t *s)
-{
-}
-
-DLLEXPORT stream_interface_t null_funcs =
-    {free_null_stream, null_seek, null_seek_end, null_skip,
-     null_read, null_write, null_trunc, null_eof, null_flush};
-
-stream_t *nullstream_new()
-{
-    stream_t *s;
-
-    s = (stream_t*)obj_alloc(stream_pool);
-    s->funcs = &null_funcs;
-    s->byteswap = false;
-    s->bitpos = s->bitbuf = 0;
-    s->pos = 0;
-
-    return s;
-}
-
-void free_roms_stream(stream_t *s)
-{
-    (void)s;
-}
-
-size_t roms_write(struct _stream *s, char *data, size_t size)
-{
-    (void)s;
-    (void)data;
-    (void)size;
-    return 0;
-}
-
-size_t roms_trunc(struct _stream *s, size_t size)
-{
-    (void)size;
-    return s->size;
-}
-
-void roms_flush(struct _stream *s)
-{
-    s->bitpos = 0;
-}
-
-stream_interface_t roms_funcs =
-    {free_roms_stream, ms_seek, ms_seek_end, ms_skip,
-     ms_read, roms_write, roms_trunc, ms_eof, roms_flush};
-
-/* read-only memory stream */
-stream_t *romemstream_new(stream_t *s, char *data, size_t len)
-{
-    memstream_new(s, 0);
-
-    s->funcs = &roms_funcs;
-
-    s->data = data;
-    s->size = len;
-    s->maxsize = len+1;
-    s->pos = 0;
-    s->bitpos = s->bitbuf = 0;
-    s->byteswap = false;
-
-    return s;
-}
-
-int stream_vput_int(stream_t *s, int nargs, ...)
-{
-    u_int32_t val, i, c=0;
-    va_list ap;
-
-    va_start(ap, nargs);
-    for(i=0; i < (unsigned)nargs; i++) {
-        val = va_arg(ap, int);
-        c += stream_put_int(s, val);
-    }
-    va_end(ap);
-
-    return c;
-}
-
-// after this function you are guaranteed to be able to perform
-// operations of the kind requested.
-static int _ios_setstate(ios_t *s, iostate_t newstate)
-{
-    if (s->state != newstate) {
-        if (s->state == iost_none || s->bm == bm_mem || s->bm == bm_none) {
-        }
-        else if (s->state == iost_rd) {
-            // reading -> writing; try to put back unused buffer data
-            // todo: another possibility here is to seek back s->size bytes,
-            // not move any data, and retain the ability to seek backwards
-            // within the buffer. the downside to that would be redundant
-            // writes of stuff that was already in the file.
-            ios_skip(s, -(off_t)(s->size - s->bpos));
-            // todo: if the seek fails...?
-            _discard_partial_buffer(s);
-            // note: bitpos is left alone, so if all goes well we pick up
-            // writing exactly where we stopped reading.
-        }
-        else if (s->state == iost_wr) {
-            ios_flush(s);
-        }
-        s->state = newstate;
-    }
-
-    // now make sure buffer is set up for the state we're in
-    if (s->state == iost_wr) {
-        // TODO: fill buffer if stenciling is requested
-    }
-    else if (s->state == iost_rd) {
-        // TODO: fill buffer if needed
-    }
-
-    return 0;
-}
-
-
-/* convert double to int64 in software */
-int64_t double_to_int64(double d)
-{
-    int64_t i;
-    int ex;
-    union ieee754_double dl;
-
-    if (fabs(d) < 1) return 0;
-
-    dl.d = d;
-    ex = dl.ieee.exponent - IEEE754_DOUBLE_BIAS;
-    // fill mantissa into bits 0 to 51
-    i = ((((int64_t)dl.mantissa0)<<32) | ((int64_t)dl.mantissa1));
-    if (ex < 52)
-        i >>= (52-ex);
-    else if (ex > 52)
-        i <<= (ex-52);
-}