adding more ios functions

porting femtolisp to use ios for all I/O
This commit is contained in:
JeffBezanson 2008-08-17 18:16:31 +00:00
parent 755bb33714
commit 9acdf313b9
12 changed files with 222 additions and 200 deletions

View File

@ -39,8 +39,8 @@ value_t fl_print(value_t *args, u_int32_t nargs)
{
unsigned i;
for (i=0; i < nargs; i++)
print(stdout, args[i], 0);
fputc('\n', stdout);
print(ios_stdout, args[i], 0);
ios_putc('\n', ios_stdout);
return nargs ? args[nargs-1] : NIL;
}
@ -48,7 +48,7 @@ value_t fl_princ(value_t *args, u_int32_t nargs)
{
unsigned i;
for (i=0; i < nargs; i++)
print(stdout, args[i], 1);
print(ios_stdout, args[i], 1);
return nargs ? args[nargs-1] : NIL;
}
@ -56,7 +56,7 @@ value_t fl_read(value_t *args, u_int32_t nargs)
{
(void)args;
argcount("read", nargs, 0);
return read_sexpr(stdin);
return read_sexpr(ios_stdin);
}
value_t fl_load(value_t *args, u_int32_t nargs)

View File

@ -32,7 +32,7 @@ value_t autoreleasesym, typeofsym, sizeofsym;
static void cvalue_init(value_t type, value_t *vs, u_int32_t nv, void *dest);
void cvalue_print(FILE *f, value_t v, int princ);
void cvalue_print(ios_t *f, value_t v, int princ);
// exported guest functions
value_t cvalue_new(value_t *args, u_int32_t nargs);
value_t cvalue_sizeof(value_t *args, u_int32_t nargs);

View File

@ -84,7 +84,7 @@ value_t defunsym, defmacrosym, forsym, labelsym, printprettysym;
static value_t eval_sexpr(value_t e, uint32_t penv, int tail);
static value_t *alloc_words(int n);
static value_t relocate(value_t v);
static void do_print(FILE *f, value_t v, int princ);
static void do_print(ios_t *f, value_t v, int princ);
typedef struct _readstate_t {
ptrhash_t backrefs;
@ -1389,62 +1389,64 @@ static void print_toplevel_exception()
{
if (iscons(lasterror) && car_(lasterror) == TypeError &&
llength(lasterror) == 4) {
fprintf(stderr, "type-error: ");
print(stderr, car_(cdr_(lasterror)), 1);
fprintf(stderr, ": expected ");
print(stderr, car_(cdr_(cdr_(lasterror))), 1);
fprintf(stderr, ", got ");
print(stderr, car_(cdr_(cdr_(cdr_(lasterror)))), 0);
ios_printf(ios_stderr, "type-error: ");
print(ios_stderr, car_(cdr_(lasterror)), 1);
ios_printf(ios_stderr, ": expected ");
print(ios_stderr, car_(cdr_(cdr_(lasterror))), 1);
ios_printf(ios_stderr, ", got ");
print(ios_stderr, car_(cdr_(cdr_(cdr_(lasterror)))), 0);
}
else if (iscons(lasterror) && car_(lasterror) == UnboundError &&
iscons(cdr_(lasterror))) {
fprintf(stderr, "unbound-error: eval: variable %s has no value",
ios_printf(ios_stderr, "unbound-error: eval: variable %s has no value",
(symbol_name(car_(cdr_(lasterror)))));
}
else if (iscons(lasterror) && car_(lasterror) == Error) {
value_t v = cdr_(lasterror);
fprintf(stderr, "error: ");
ios_printf(ios_stderr, "error: ");
while (iscons(v)) {
print(stderr, car_(v), 1);
print(ios_stderr, car_(v), 1);
v = cdr_(v);
}
}
else {
if (lasterror != NIL) {
if (!lerrorbuf[0])
fprintf(stderr, "*** Unhandled exception: ");
print(stderr, lasterror, 0);
ios_printf(ios_stderr, "*** Unhandled exception: ");
print(ios_stderr, lasterror, 0);
if (lerrorbuf[0])
fprintf(stderr, ": ");
ios_printf(ios_stderr, ": ");
}
}
if (lerrorbuf[0])
fprintf(stderr, "%s", lerrorbuf);
ios_printf(ios_stderr, "%s", lerrorbuf);
}
value_t load_file(char *fname)
{
value_t volatile e, v=NIL;
FILE * volatile f = fopen(fname, "r");
ios_t fi;
ios_t * volatile f;
f = &fi; f = ios_file(f, fname, 0, 0);
if (f == NULL) lerror(IOError, "file \"%s\" not found", fname);
FL_TRY {
while (1) {
e = read_sexpr(f);
//print(stdout,e,0); printf("\n");
if (feof(f)) break;
//print(ios_stdout,e,0); ios_puts("\n", ios_stdout);
if (ios_eof(f)) break;
v = toplevel_eval(e);
}
}
FL_CATCH {
fclose(f);
ios_close(f);
size_t msglen = strlen(lerrorbuf);
snprintf(&lerrorbuf[msglen], sizeof(lerrorbuf)-msglen,
"\nin file \"%s\"", fname);
lerrorbuf[sizeof(lerrorbuf)-1] = '\0';
raise(lasterror);
}
fclose(f);
ios_close(f);
return v;
}
@ -1477,7 +1479,7 @@ int main(int argc, char *argv[])
lerrorbuf[0] = '\0';
lasterror = NIL;
fprintf(stderr, "\n\n");
ios_puts("\n\n", ios_stderr);
goto repl;
}
load_file("system.lsp");
@ -1488,13 +1490,13 @@ int main(int argc, char *argv[])
printf(";-------------------|----------------------------------------------------------\n\n");
repl:
while (1) {
printf("> ");
v = read_sexpr(stdin);
if (feof(stdin)) break;
print(stdout, v=toplevel_eval(v), 0);
ios_puts("> ", ios_stdout); ios_flush(ios_stdout);
v = read_sexpr(ios_stdin);
if (ios_eof(ios_stdin)) break;
print(ios_stdout, v=toplevel_eval(v), 0);
set(symbol("that"), v);
printf("\n\n");
ios_puts("\n\n", ios_stdout);
}
printf("\n");
ios_puts("\n", ios_stdout);
return 0;
}

View File

@ -105,8 +105,8 @@ enum {
extern value_t NIL, T;
/* read, eval, print main entry points */
value_t read_sexpr(FILE *f);
void print(FILE *f, value_t v, int princ);
value_t read_sexpr(ios_t *f);
void print(ios_t *f, value_t v, int princ);
value_t toplevel_eval(value_t expr);
value_t apply(value_t f, value_t l);
value_t load_file(char *fname);

View File

@ -3,27 +3,27 @@ static u_int32_t printlabel;
static int print_pretty;
static int HPOS, VPOS;
static void outc(char c, FILE *f)
static void outc(char c, ios_t *f)
{
fputc(c, f);
ios_putc(c, f);
HPOS++;
}
static void outs(char *s, FILE *f)
static void outs(char *s, ios_t *f)
{
fputs(s, f);
ios_puts(s, f);
HPOS += u8_strwidth(s);
}
static void outindent(int n, FILE *f)
static void outindent(int n, ios_t *f)
{
fputc('\n', f);
ios_putc('\n', f);
VPOS++;
HPOS = n;
while (n >= 8) {
fputc('\t', f);
ios_putc('\t', f);
n -= 8;
}
while (n) {
fputc(' ', f);
ios_putc(' ', f);
n--;
}
}
@ -65,7 +65,7 @@ static void print_traverse(value_t v)
}
}
static void print_symbol_name(FILE *f, char *name)
static void print_symbol_name(ios_t *f, char *name)
{
int i, escape=0, charescape=0;
@ -202,7 +202,7 @@ static int blockindent(value_t v)
return (allsmallp(v) > 9);
}
static void print_pair(FILE *f, value_t v, int princ)
static void print_pair(ios_t *f, value_t v, int princ)
{
value_t cd;
char *op = NULL;
@ -286,16 +286,16 @@ static void print_pair(FILE *f, value_t v, int princ)
}
}
void cvalue_print(FILE *f, value_t v, int princ);
void cvalue_print(ios_t *f, value_t v, int princ);
static void do_print(FILE *f, value_t v, int princ)
static void do_print(ios_t *f, value_t v, int princ)
{
value_t label;
char *name;
switch (tag(v)) {
case TAG_NUM :
case TAG_NUM1: HPOS+=fprintf(f, "%ld", numval(v)); break;
case TAG_NUM1: HPOS+=ios_printf(f, "%ld", numval(v)); break;
case TAG_SYM:
name = symbol_name(v);
if (princ)
@ -323,10 +323,10 @@ static void do_print(FILE *f, value_t v, int princ)
if ((label=(value_t)ptrhash_get(&printconses, (void*)v)) !=
(value_t)PH_NOTFOUND) {
if (!ismarked(v)) {
HPOS+=fprintf(f, "#%ld#", numval(label));
HPOS+=ios_printf(f, "#%ld#", numval(label));
return;
}
HPOS+=fprintf(f, "#%ld=", numval(label));
HPOS+=ios_printf(f, "#%ld=", numval(label));
}
if (isvector(v)) {
outc('[', f);
@ -362,7 +362,7 @@ static void do_print(FILE *f, value_t v, int princ)
}
}
void print_string(FILE *f, char *str, size_t sz)
void print_string(ios_t *f, char *str, size_t sz)
{
char buf[512];
size_t i = 0;
@ -381,7 +381,7 @@ static numerictype_t sym_to_numtype(value_t type);
// for example #int32(0) can be printed as just 0. this is used
// printing in a context where a type is already implied, e.g. inside
// an array.
static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
static void cvalue_printdata(ios_t *f, void *data, size_t len, value_t type,
int princ, int weak)
{
int64_t tmp=0;
@ -392,11 +392,11 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
if (princ)
outc(ch, f);
else if (weak)
HPOS+=fprintf(f, "%hhu", ch);
HPOS+=ios_printf(f, "%hhu", ch);
else if (isprint(ch))
HPOS+=fprintf(f, "#\\%c", ch);
HPOS+=ios_printf(f, "#\\%c", ch);
else
HPOS+=fprintf(f, "#char(%hhu)", ch);
HPOS+=ios_printf(f, "#char(%hhu)", ch);
}
/*
else if (type == ucharsym) {
@ -405,8 +405,8 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
outc(ch, f);
else {
if (!weak)
fprintf(f, "#uchar(");
fprintf(f, "%hhu", ch);
ios_printf(f, "#uchar(");
ios_printf(f, "%hhu", ch);
if (!weak)
outs(")", f);
}
@ -416,7 +416,7 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
uint32_t wc = *(uint32_t*)data;
char seq[8];
if (weak)
HPOS+=fprintf(f, "%d", (int)wc);
HPOS+=ios_printf(f, "%d", (int)wc);
else if (princ || (iswprint(wc) && wc>0x7f)) {
// reader only reads #\c syntax as wchar if the code is >0x7f
size_t nb = u8_toutf8(seq, sizeof(seq), &wc, 1);
@ -426,7 +426,7 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
outs(seq, f);
}
else {
HPOS+=fprintf(f, "#%s(%d)", symbol_name(type), (int)wc);
HPOS+=ios_printf(f, "#%s(%d)", symbol_name(type), (int)wc);
}
}
else if (type == int64sym
@ -437,12 +437,12 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
int64_t i64 = *(int64_t*)data;
if (fits_fixnum(i64) || princ) {
if (weak || princ)
HPOS+=fprintf(f, "%lld", i64);
HPOS+=ios_printf(f, "%lld", i64);
else
HPOS+=fprintf(f, "#%s(%lld)", symbol_name(type), i64);
HPOS+=ios_printf(f, "#%s(%lld)", symbol_name(type), i64);
}
else
HPOS+=fprintf(f, "#%s(0x%08x%08x)", symbol_name(type),
HPOS+=ios_printf(f, "#%s(0x%08x%08x)", symbol_name(type),
(uint32_t)(i64>>32),
(uint32_t)(i64));
}
@ -454,12 +454,12 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
uint64_t ui64 = *(uint64_t*)data;
if (fits_fixnum(ui64) || princ) {
if (weak || princ)
HPOS+=fprintf(f, "%llu", ui64);
HPOS+=ios_printf(f, "%llu", ui64);
else
HPOS+=fprintf(f, "#%s(%llu)", symbol_name(type), ui64);
HPOS+=ios_printf(f, "#%s(%llu)", symbol_name(type), ui64);
}
else
HPOS+=fprintf(f, "#%s(0x%08x%08x)", symbol_name(type),
HPOS+=ios_printf(f, "#%s(0x%08x%08x)", symbol_name(type),
(uint32_t)(ui64>>32),
(uint32_t)(ui64));
}
@ -479,9 +479,9 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
}
else {
if (!DFINITE(d))
HPOS+=fprintf(f, "#%s(\"%s\")", symbol_name(type), buf);
HPOS+=ios_printf(f, "#%s(\"%s\")", symbol_name(type), buf);
else
HPOS+=fprintf(f, "#%s(%s)", symbol_name(type), buf);
HPOS+=ios_printf(f, "#%s(%s)", symbol_name(type), buf);
}
}
else if (issymbol(type)) {
@ -490,12 +490,12 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
tmp = conv_to_int64(data, sym_to_numtype(type));
if (fits_fixnum(tmp) || princ) {
if (weak || princ)
HPOS+=fprintf(f, "%lld", tmp);
HPOS+=ios_printf(f, "%lld", tmp);
else
HPOS+=fprintf(f, "#%s(%lld)", symbol_name(type), tmp);
HPOS+=ios_printf(f, "#%s(%lld)", symbol_name(type), tmp);
}
else
HPOS+=fprintf(f, "#%s(0x%08x)", symbol_name(type),
HPOS+=ios_printf(f, "#%s(0x%08x)", symbol_name(type),
(uint32_t)(tmp&0xffffffff));
}
else if (iscons(type)) {
@ -514,7 +514,7 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
}
if (eltype == charsym) {
if (princ) {
fwrite(data, 1, len, f);
ios_write(f, data, len);
}
else {
print_string(f, (char*)data, len);
@ -562,13 +562,13 @@ static void cvalue_printdata(FILE *f, void *data, size_t len, value_t type,
}
}
void cvalue_print(FILE *f, value_t v, int princ)
void cvalue_print(ios_t *f, value_t v, int princ)
{
cvalue_t *cv = (cvalue_t*)ptr(v);
void *data = cv_data(cv);
if (cv->flags.islispfunction) {
HPOS+=fprintf(f, "#<guestfunction @0x%08lx>",
HPOS+=ios_printf(f, "#<guestfunction @0x%08lx>",
(unsigned long)*(guestfunc_t*)data);
return;
}
@ -576,7 +576,7 @@ void cvalue_print(FILE *f, value_t v, int princ)
cvalue_printdata(f, data, cv_len(cv), cv_type(cv), princ, 0);
}
void print(FILE *f, value_t v, int princ)
void print(ios_t *f, value_t v, int princ)
{
print_pretty = (symbol_value(printprettysym) != NIL);
ptrhash_reset(&printconses, 32);

View File

@ -55,21 +55,21 @@ static u_int32_t toktype = TOK_NONE;
static value_t tokval;
static char buf[256];
static char nextchar(FILE *f)
static char nextchar(ios_t *f)
{
int ch;
char c;
do {
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
return 0;
c = (char)ch;
if (c == ';') {
// single-line comment
do {
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
return 0;
} while ((char)ch != '\n');
c = (char)ch;
@ -91,14 +91,14 @@ static void accumchar(char c, int *pi)
}
// return: 1 if escaped (forced to be symbol)
static int read_token(FILE *f, char c, int digits)
static int read_token(ios_t *f, char c, int digits)
{
int i=0, ch, escaped=0, issym=0, first=1;
while (1) {
if (!first) {
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
goto terminate;
c = (char)ch;
}
@ -109,8 +109,8 @@ static int read_token(FILE *f, char c, int digits)
}
else if (c == '\\') {
issym = 1;
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
goto terminate;
accumchar((char)ch, &i);
}
@ -121,13 +121,13 @@ static int read_token(FILE *f, char c, int digits)
accumchar(c, &i);
}
}
ungetc(c, f);
ios_ungetc(c, f);
terminate:
buf[i++] = '\0';
return issym;
}
static u_int32_t peek(FILE *f)
static u_int32_t peek(ios_t *f)
{
char c, *end;
fixnum_t x;
@ -136,7 +136,7 @@ static u_int32_t peek(FILE *f)
if (toktype != TOK_NONE)
return toktype;
c = nextchar(f);
if (feof(f)) return TOK_NONE;
if (ios_eof(f)) return TOK_NONE;
if (c == '(') {
toktype = TOK_OPEN;
}
@ -159,8 +159,8 @@ static u_int32_t peek(FILE *f)
toktype = TOK_DOUBLEQUOTE;
}
else if (c == '#') {
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
lerror(ParseError, "read: invalid read macro");
if ((char)ch == '.') {
toktype = TOK_SHARPDOT;
@ -169,8 +169,8 @@ static u_int32_t peek(FILE *f)
toktype = TOK_SHARPQUOTE;
}
else if ((char)ch == '\\') {
u_int32_t cval = u8_fgetc(f);
if (cval == UEOF)
uint32_t cval;
if (ios_getutf8(f, &cval) == IOS_EOF)
lerror(ParseError, "read: end of input in character constant");
toktype = TOK_NUM;
tokval = fixnum(cval);
@ -189,7 +189,7 @@ static u_int32_t peek(FILE *f)
}
else if (isdigit((char)ch)) {
read_token(f, (char)ch, 1);
c = (char)fgetc(f);
c = (char)ios_getc(f);
if (c == '#')
toktype = TOK_BACKREF;
else if (c == '=')
@ -205,19 +205,19 @@ static u_int32_t peek(FILE *f)
else if ((char)ch == '!') {
// #! single line comment for shbang script support
do {
ch = fgetc(f);
} while (ch != EOF && (char)ch != '\n');
ch = ios_getc(f);
} while (ch != IOS_EOF && (char)ch != '\n');
return peek(f);
}
else if ((char)ch == '|') {
// multiline comment
while (1) {
ch = fgetc(f);
ch = ios_getc(f);
hashpipe_got:
if (ch == EOF)
if (ch == IOS_EOF)
lerror(ParseError, "read: eof within comment");
if ((char)ch == '|') {
ch = fgetc(f);
ch = ios_getc(f);
if ((char)ch == '#')
break;
goto hashpipe_got;
@ -228,9 +228,9 @@ static u_int32_t peek(FILE *f)
}
else if ((char)ch == ':') {
// gensym
ch = fgetc(f);
ch = ios_getc(f);
if ((char)ch == 'g')
ch = fgetc(f);
ch = ios_getc(f);
read_token(f, (char)ch, 0);
errno = 0;
x = strtol(buf, &end, 10);
@ -256,15 +256,15 @@ static u_int32_t peek(FILE *f)
}
else if (c == ',') {
toktype = TOK_COMMA;
ch = fgetc(f);
if (ch == EOF)
ch = ios_getc(f);
if (ch == IOS_EOF)
return toktype;
if ((char)ch == '@')
toktype = TOK_COMMAAT;
else if ((char)ch == '.')
toktype = TOK_COMMADOT;
else
ungetc((char)ch, f);
ios_ungetc((char)ch, f);
}
else {
if (!read_token(f, c, 0)) {
@ -286,9 +286,9 @@ static u_int32_t peek(FILE *f)
return toktype;
}
static value_t do_read_sexpr(FILE *f, value_t label);
static value_t do_read_sexpr(ios_t *f, value_t label);
static value_t read_vector(FILE *f, value_t label, u_int32_t closer)
static value_t read_vector(ios_t *f, value_t label, u_int32_t closer)
{
value_t v=alloc_vector(4, 1), elt;
u_int32_t i=0;
@ -296,7 +296,7 @@ static value_t read_vector(FILE *f, value_t label, u_int32_t closer)
if (label != UNBOUND)
ptrhash_put(&readstate->backrefs, (void*)label, (void*)v);
while (peek(f) != closer) {
if (feof(f))
if (ios_eof(f))
lerror(ParseError, "read: unexpected end of input");
if (i >= vector_size(v))
Stack[SP-1] = vector_grow(v);
@ -310,7 +310,7 @@ static value_t read_vector(FILE *f, value_t label, u_int32_t closer)
return POP();
}
static value_t read_string(FILE *f)
static value_t read_string(ios_t *f)
{
char *buf, *temp;
char eseq[10];
@ -330,16 +330,16 @@ static value_t read_string(FILE *f)
}
buf = temp;
}
c = fgetc(f);
if (c == EOF) {
c = ios_getc(f);
if (c == IOS_EOF) {
free(buf);
lerror(ParseError, "read: unexpected end of input in string");
}
if (c == '"')
break;
else if (c == '\\') {
c = fgetc(f);
if (c == EOF) {
c = ios_getc(f);
if (c == IOS_EOF) {
free(buf);
lerror(ParseError, "read: end of input in escape sequence");
}
@ -347,9 +347,9 @@ static value_t read_string(FILE *f)
if (octal_digit(c)) {
do {
eseq[j++] = c;
c = fgetc(f);
} while (octal_digit(c) && j<3 && (c!=EOF));
if (c!=EOF) ungetc(c, f);
c = ios_getc(f);
} while (octal_digit(c) && j<3 && (c!=IOS_EOF));
if (c!=IOS_EOF) ios_ungetc(c, f);
eseq[j] = '\0';
wc = strtol(eseq, NULL, 8);
i += u8_wc_toutf8(&buf[i], wc);
@ -358,12 +358,12 @@ static value_t read_string(FILE *f)
(c=='u' && (ndig=4)) ||
(c=='U' && (ndig=8))) {
wc = c;
c = fgetc(f);
while (hex_digit(c) && j<ndig && (c!=EOF)) {
c = ios_getc(f);
while (hex_digit(c) && j<ndig && (c!=IOS_EOF)) {
eseq[j++] = c;
c = fgetc(f);
c = ios_getc(f);
}
if (c!=EOF) ungetc(c, f);
if (c!=IOS_EOF) ios_ungetc(c, f);
eseq[j] = '\0';
if (j) wc = strtol(eseq, NULL, 16);
i += u8_wc_toutf8(&buf[i], wc);
@ -398,7 +398,7 @@ static value_t read_string(FILE *f)
// build a list of conses. this is complicated by the fact that all conses
// can move whenever a new cons is allocated. we have to refer to every cons
// through a handle to a relocatable pointer (i.e. a pointer on the stack).
static void read_list(FILE *f, value_t *pval, value_t label)
static void read_list(ios_t *f, value_t *pval, value_t label)
{
value_t c, *pc;
u_int32_t t;
@ -407,7 +407,7 @@ static void read_list(FILE *f, value_t *pval, value_t label)
pc = &Stack[SP-1]; // to keep track of current cons cell
t = peek(f);
while (t != TOK_CLOSE) {
if (feof(f))
if (ios_eof(f))
lerror(ParseError, "read: unexpected end of input");
c = mk_cons(); car_(c) = cdr_(c) = NIL;
if (iscons(*pc)) {
@ -428,7 +428,7 @@ static void read_list(FILE *f, value_t *pval, value_t label)
c = do_read_sexpr(f,UNBOUND);
cdr_(*pc) = c;
t = peek(f);
if (feof(f))
if (ios_eof(f))
lerror(ParseError, "read: unexpected end of input");
if (t != TOK_CLOSE)
lerror(ParseError, "read: expected ')'");
@ -439,7 +439,7 @@ static void read_list(FILE *f, value_t *pval, value_t label)
}
// label is the backreference we'd like to fix up with this read
static value_t do_read_sexpr(FILE *f, value_t label)
static value_t do_read_sexpr(ios_t *f, value_t label)
{
value_t v, sym, oldtokval, *head;
value_t *pv;
@ -529,7 +529,7 @@ static value_t do_read_sexpr(FILE *f, value_t label)
return NIL;
}
value_t read_sexpr(FILE *f)
value_t read_sexpr(ios_t *f)
{
value_t v;
readstate_t state;

View File

@ -37,6 +37,7 @@
l))
(time (progn (print (torus 100 100)) nil))
;(time (dotimes (i 1) (load "100x100.lsp")))
; with ltable
; printing time: 0.415sec
; reading time: 0.165sec

View File

@ -129,4 +129,6 @@ void llt_init()
flt_tolerance(5e-6);
randomize();
ios_init_stdstreams();
}

108
llt/ios.c
View File

@ -302,6 +302,25 @@ size_t ios_readall(ios_t *s, char *dest, size_t n)
return _ios_read(s, dest, n, 1);
}
size_t ios_readprep(ios_t *s, size_t n)
{
size_t space = s->size - s->bpos;
if (s->state == bst_wr)
return space;
if (space >= n || s->bm == bm_mem || s->fd == -1)
return space;
if (s->maxsize < s->bpos+n) {
if (_buf_realloc(s, s->maxsize + n)==NULL)
return space;
}
size_t got;
int result = _os_read(s->fd, s->buf+s->size, s->maxsize - s->size, &got);
if (result)
return space;
s->size += got;
return s->size - s->bpos;
}
size_t ios_write(ios_t *s, char *data, size_t n)
{
if (n == 0) return 0;
@ -421,10 +440,13 @@ int ios_eof(ios_t *s)
return 1;
if (s->_eof)
return 1;
return 0;
/*
if (_fd_available(s->fd))
return 0;
s->_eof = 1;
return 1;
*/
}
static void _discard_partial_buffer(ios_t *s)
@ -646,36 +668,22 @@ ios_t *ios_fd(ios_t *s, long fd, int isfile)
return s;
}
ios_t *ios_stdin()
{
static ios_t *_ios_stdin = NULL;
if (_ios_stdin == NULL) {
_ios_stdin = malloc(sizeof(ios_t));
ios_fd(_ios_stdin, STDIN_FILENO, 0);
}
return _ios_stdin;
}
ios_t *ios_stdin = NULL;
ios_t *ios_stdout = NULL;
ios_t *ios_stderr = NULL;
ios_t *ios_stdout()
void ios_init_stdstreams()
{
static ios_t *_ios_stdout = NULL;
if (_ios_stdout == NULL) {
_ios_stdout = malloc(sizeof(ios_t));
ios_fd(_ios_stdout, STDOUT_FILENO, 0);
_ios_stdout->bm = bm_line;
}
return _ios_stdout;
}
ios_stdin = malloc(sizeof(ios_t));
ios_fd(ios_stdin, STDIN_FILENO, 0);
ios_t *ios_stderr()
{
static ios_t *_ios_stderr = NULL;
if (_ios_stderr == NULL) {
_ios_stderr = malloc(sizeof(ios_t));
ios_fd(_ios_stderr, STDERR_FILENO, 0);
_ios_stderr->bm = bm_none;
}
return _ios_stderr;
ios_stdout = malloc(sizeof(ios_t));
ios_fd(ios_stdout, STDOUT_FILENO, 0);
ios_stdout->bm = bm_line;
ios_stderr = malloc(sizeof(ios_t));
ios_fd(ios_stderr, STDERR_FILENO, 0);
ios_stderr->bm = bm_none;
}
/* higher level interface */
@ -689,10 +697,11 @@ int ios_putc(int c, ios_t *s)
int ios_getc(ios_t *s)
{
if (s->bpos < s->size)
return s->buf[s->bpos++];
if (s->_eof) return IOS_EOF;
char ch;
size_t n = ios_read(s, &ch, 1);
if (n < 1)
if (ios_read(s, &ch, 1) < 1)
return IOS_EOF;
return (int)ch;
}
@ -716,20 +725,53 @@ int ios_ungetc(int c, ios_t *s)
return c;
}
int ios_getutf8(ios_t *s, uint32_t *pwc)
{
int c;
size_t sz;
char c0;
char buf[8];
c = ios_getc(s);
if (c == IOS_EOF)
return IOS_EOF;
c0 = (char)c;
sz = u8_seqlen(&c0)-1;
if (sz == 0) {
*pwc = (uint32_t)c0;
return 1;
}
if (ios_ungetc(c, s) == IOS_EOF)
return IOS_EOF;
if (ios_readprep(s, sz) < sz)
// NOTE: this can return EOF even if some bytes are available
return IOS_EOF;
size_t i = s->bpos;
*pwc = u8_nextchar(s->buf, &i);
ios_read(s, buf, sz+1);
return 1;
}
int ios_printf(ios_t *s, char *format, ...)
{
char *str;
char buf[512];
char *str=&buf[0];
va_list args;
int c;
va_start(args, format);
// TODO: avoid copy
int c = vasprintf(&str, format, args);
c = vsnprintf(buf, sizeof(buf), format, args);
if ((size_t)c >= sizeof(buf))
c = vasprintf(&str, format, args);
va_end(args);
if (c == -1) return c;
if (c < 0) return c;
ios_write(s, str, c);
free(str);
if (str != &buf[0]) free(str);
return c;
}

View File

@ -9,7 +9,7 @@ typedef enum { bm_none, bm_line, bm_block, bm_mem } bufmode_t;
typedef enum { bst_none, bst_rd, bst_wr } bufstate_t;
#define IOS_INLSIZE 54
#define IOS_BUFSIZE 4095
#define IOS_BUFSIZE 8191
typedef struct {
bufmode_t bm;
@ -79,8 +79,8 @@ 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);
int ios_copyall(ios_t *to, ios_t *from);
// ensure at least n bytes are buffered if possible. returns actual #.
//size_t ios_ensure(ios_t *from, size_t n);
// ensure at least n bytes are buffered if possible. returns # available.
size_t ios_readprep(ios_t *from, size_t n);
//void ios_lock(ios_t *s);
//int ios_trylock(ios_t *s);
//int ios_unlock(ios_t *s);
@ -91,9 +91,10 @@ ios_t *ios_mem(ios_t *s, size_t initsize);
ios_t *ios_str(ios_t *s, char *str);
ios_t *ios_fd(ios_t *s, long fd, int isfile);
// todo: ios_socket
ios_t *ios_stdin();
ios_t *ios_stdout();
ios_t *ios_stderr();
extern ios_t *ios_stdin;
extern ios_t *ios_stdout;
extern ios_t *ios_stderr;
void ios_init_stdstreams();
/* high-level functions - output */
int ios_putnum(ios_t *s, char *data, uint32_t type);

View File

@ -80,7 +80,7 @@ size_t u8_codingsize(u_int32_t *wcstr, size_t n)
sz = dest size in # of wide characters
returns # characters converted
if sz = srcsz+1 (i.e. 4*srcsz+4 bytes), there will always be enough space.
if sz == srcsz+1 (i.e. 4*srcsz+4 bytes), there will always be enough space.
*/
size_t u8_toucs(u_int32_t *dest, size_t sz, const char *src, size_t srcsz)
{
@ -565,23 +565,25 @@ int u8_is_locale_utf8(const char *locale)
size_t u8_vprintf(const char *fmt, va_list ap)
{
size_t cnt, sz=0, nc;
size_t cnt, sz=0, nc, needfree=0;
char *buf;
u_int32_t *wcs;
sz = 512;
buf = (char*)alloca(sz);
try_print:
cnt = vsnprintf(buf, sz, fmt, ap);
if ((ssize_t)cnt < 0)
return 0;
if (cnt >= sz) {
buf = (char*)alloca(cnt - sz + 1);
sz = cnt + 1;
goto try_print;
buf = (char*)malloc(cnt + 1);
needfree = 1;
vsnprintf(buf, cnt+1, fmt, ap);
}
wcs = (u_int32_t*)alloca((cnt+1) * sizeof(u_int32_t));
nc = u8_toucs(wcs, cnt+1, buf, cnt);
wcs[nc] = 0;
printf("%ls", (wchar_t*)wcs);
if (needfree) free(buf);
return nc;
}
@ -702,27 +704,3 @@ int u8_reverse(char *dest, char * src, size_t len)
}
return 0;
}
u_int32_t u8_fgetc(FILE *f)
{
int amt=0, sz, c;
u_int32_t ch=0;
char c0;
c = fgetc(f);
if (c == EOF)
return UEOF;
ch = (u_int32_t)c;
c0 = (char)ch;
amt = sz = u8_seqlen(&c0);
while (--amt) {
ch <<= 6;
c = fgetc(f);
if (c == EOF)
return UEOF;
ch += (u_int32_t)c;
}
ch -= offsetsFromUTF8[sz-1];
return ch;
}

View File

@ -121,8 +121,4 @@ int u8_isvalid(const char *str, int length);
be allocated to at least len+1 bytes. returns 1 for error, 0 otherwise */
int u8_reverse(char *dest, char *src, size_t len);
#include <stdio.h> // temporary, until u8_fgetc is gone
/* read a UTF-8 sequence from a stream and return a wide character or UEOF */
u_int32_t u8_fgetc(FILE *f);
#endif