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 \
|
mathlib.c \
|
||||||
iolib.c \
|
iolib.c \
|
||||||
iolib.h \
|
iolib.h \
|
||||||
|
bitslib.c \
|
||||||
misc.c \
|
misc.c \
|
||||||
nasal.h \
|
nasal.h \
|
||||||
parse.c parse.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;
|
naRef result;
|
||||||
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
|
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
|
||||||
int i=0, sz = 128;
|
int i=0, sz = 128;
|
||||||
char* buf;
|
char c, *buf;
|
||||||
if(!g || g->type != &naStdIOType)
|
if(!g || g->type != &naStdIOType)
|
||||||
naRuntimeError(ctx, "bad argument to readln()");
|
naRuntimeError(ctx, "bad argument to readln()");
|
||||||
buf = naAlloc(sz);
|
buf = naAlloc(sz);
|
||||||
while(1) {
|
while(1) {
|
||||||
char c = getcguard(ctx, g->handle, buf);
|
c = getcguard(ctx, g->handle, buf);
|
||||||
if(c == EOF || c == '\n') break;
|
if(c == EOF || c == '\n') break;
|
||||||
if(c == '\r') {
|
if(c == '\r') {
|
||||||
char c2 = getcguard(ctx, g->handle, buf);
|
char c2 = getcguard(ctx, g->handle, buf);
|
||||||
|
Loading…
Reference in New Issue
Block a user