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:
parent
29eb566448
commit
7d631e4959
@ -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
94
simgear/nasal/bitslib.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user