Fix broken checkin in iolib.c. Also add the 'bits' library, which has a buf()

function needed to make convenient use of io.read().
This commit is contained in:
andy 2006-03-15 19:42:37 +00:00
parent 29eb566448
commit 7d631e4959
3 changed files with 97 additions and 2 deletions

View File

@ -15,6 +15,7 @@ libsgnasal_a_SOURCES = \
mathlib.c \
iolib.c \
iolib.h \
bitslib.c \
misc.c \
nasal.h \
parse.c parse.h \

94
simgear/nasal/bitslib.c Normal file
View File

@ -0,0 +1,94 @@
#include <string.h>
#include "data.h"
// Note that this currently supports a maximum field width of 32
// bits (i.e. an unsigned int). Using a 64 bit integer would stretch
// that beyond what is representable in the double result, but
// requires portability work.
#define BIT(s,l,n) s[l-1-((n)>>3)] & (1<<((n)&7))
#define CLRB(s,l,n) s[l-1-((n)>>3)] &= ~(1<<((n)&7))
#define SETB(s,l,n) s[l-1-((n)>>3)] |= 1<<((n)&7)
static unsigned int fld(naContext c, unsigned char* s,
int slen, int bit, int flen)
{
int i;
unsigned int fld = 0;
if(bit + flen > 8*slen) naRuntimeError(c, "bitfield out of bounds");
for(i=0; i<flen; i++) if(BIT(s, slen, i+bit)) fld |= (1<<i);
return fld;
}
static void setfld(naContext c, unsigned char* s, int slen,
int bit, int flen, unsigned int fld)
{
int i;
if(bit + flen > 8*slen) naRuntimeError(c, "bitfield out of bounds");
for(i=0; i<flen; i++)
if(fld & (1<<i)) SETB(s, slen, i+bit);
else CLRB(s, slen, i+bit);
}
static naRef dofld(naContext c, int argc, naRef* args, int sign)
{
struct naStr* s = argc > 0 ? args[0].ref.ptr.str : 0;
int bit = argc > 1 ? (int)naNumValue(args[1]).num : -1;
int len = argc > 2 ? (int)naNumValue(args[2]).num : -1;
unsigned int f;
if(!s || !MUTABLE(args[0]) || bit < 0 || len < 0)
naRuntimeError(c, "missing/bad argument to fld/sfld");
f = fld(c, s->data, s->len, bit, len);
if(!sign) return naNum(f);
if(f & (1 << (len-1))) f |= ~((1<<len)-1); // sign extend
return naNum((signed int)f);
}
static naRef f_sfld(naContext c, naRef me, int argc, naRef* args)
{
return dofld(c, argc, args, 1);
}
static naRef f_fld(naContext c, naRef me, int argc, naRef* args)
{
return dofld(c, argc, args, 0);
}
static naRef f_setfld(naContext c, naRef me, int argc, naRef* args)
{
struct naStr* s = argc > 0 ? args[0].ref.ptr.str : 0;
int bit = argc > 1 ? (int)naNumValue(args[1]).num : -1;
int len = argc > 2 ? (int)naNumValue(args[2]).num : -1;
naRef val = argc > 3 ? naNumValue(args[3]) : naNil();
if(!argc || !MUTABLE(args[0])|| bit < 0 || len < 0 || IS_NIL(val))
naRuntimeError(c, "missing/bad argument to setfld");
setfld(c, s->data, s->len, bit, len, (unsigned int)val.num);
return naNil();
}
static naRef f_buf(naContext c, naRef me, int argc, naRef* args)
{
naRef len = argc ? naNumValue(args[0]) : naNil();
if(IS_NIL(len)) naRuntimeError(c, "missing/bad argument to buf");
return naStr_buf(naNewString(c), (int)len.num);
}
static struct func { char* name; naCFunction func; } funcs[] = {
{ "sfld", f_sfld },
{ "fld", f_fld },
{ "setfld", f_setfld },
{ "buf", f_buf },
};
naRef naBitsLib(naContext c)
{
naRef namespace = naNewHash(c);
int i, n = sizeof(funcs)/sizeof(struct func);
for(i=0; i<n; i++) {
naRef code = naNewCCode(c, funcs[i].func);
naRef name = naStr_fromdata(naNewString(c),
funcs[i].name, strlen(funcs[i].name));
naHash_set(namespace, name, naNewFunc(c, code));
}
return namespace;
}

View File

@ -158,12 +158,12 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
naRef result;
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
int i=0, sz = 128;
char* buf;
char c, *buf;
if(!g || g->type != &naStdIOType)
naRuntimeError(ctx, "bad argument to readln()");
buf = naAlloc(sz);
while(1) {
char c = getcguard(ctx, g->handle, buf);
c = getcguard(ctx, g->handle, buf);
if(c == EOF || c == '\n') break;
if(c == '\r') {
char c2 = getcguard(ctx, g->handle, buf);