#include <u.h>
#include <libc.h>
#include <thread.h>
#include <bio.h>
#include <draw.h>
#include "debug.h"
#include "lex.h"
#include "sky.h"
#include "gfx.h"
#include "dat.h"
#include "fns.h"
enum
{
DTstr,
DTdouble,
DTint,
};
Cfg *cfg;
struct Skynode* mkskynode(void);
void* findaddr(Rune *id, int *typ, int *dtyp);
int
cfginit(void)
{
if((cfg = malloc(sizeof(Cfg))) == nil)
return Ememory;
if((cfg->head=mkskynode())==nil)
return Ememory;
memset(cfg->head, 0, sizeof(struct Skynode));
cfg->obs = defaultObs;
cfg->camera = defaultCamera;
cfg->samplerate = 10;
cfg->jd = time(0)/86400.0 + 2440587.5; /* now */
cfg->atm = 1;
cfg->nobj = 0;
return 0;
}
void
cfgterm(void)
{
struct Skynode *head, *nxt;
head = cfg->head;
while(head){
nxt = head->next;
free(head);
head = nxt;
}
free(cfg);
}
Tok cfginsert(Tok *argv, int argc)
{
static Tok te[] = {
{Tempty, L"success"},
{Terror, L"invalid arguments"},
{Terror, L"out of memory"},
};
struct Skynode *head;
int typ, dtyp;
head = cfg->head;
if(argc != 1 || argv->typ != Tidentifier) return te[1];
if(findaddr(argv->str, &typ, &dtyp)) return te[1];
/* the tail node is always pre-allocated but unset */
while(head->next)
head=head->next;
if((head->next=mkskynode())==nil)
return te[2];
runestrncpy(head->id, argv->str, Ltoksize+1);
cfg->nobj++;
DBPRINT(10, "cfg.c:cfginsert cfg->nobj == %d\n", cfg->nobj);
return te[0];
}
Tok cfgset(Tok *argv, int argc)
{
static Tok te[] = {
{Tempty, L"success"},
{Terror, L"invalid arguments"},
};
struct Skynode *head;
void *addr;
int typ, dtyp;
head = cfg->head;
if(argc != 2 || (addr = findaddr(argv->str, &typ, &dtyp)) == nil) return te[1];
argv++;
if(argv->typ != typ) return te[1];
switch(dtyp){
case DTstr:
runestrncpy(addr, argv->str, Ltoksize+1);
break;
case DTdouble:
*(double*)addr = runeatof(argv->str);
break;
case DTint:
*(int*)addr = runeatof(argv->str);
break;
default:
return te[1]; /* should not happen */
}
return te[0];
}
Tok cfgget(Tok *argv, int argc)
{
static Tok te[] = {
{Tempty, L"success"},
{Terror, L"invalid arguments"},
};
struct Skynode *head;
void *addr;
int typ, dtyp;
head = cfg->head;
if(argc != 1 || (addr = findaddr(argv->str, &typ, &dtyp)) == nil) return te[1];
switch(dtyp){
case DTstr:
runestrncpy(te[0].str, addr, Ltoksize+1);
te[0].typ = Tstr;
break;
case DTdouble:
runesnprint(te[0].str, Ltoksize+1, "%f", *(double*)addr);
te[0].typ = Tdecimal;
break;
case DTint:
runesnprint(te[0].str, Ltoksize+1, "%d", *(int*)addr);
te[0].typ = Tdecimal;
break;
default:
return te[1]; /* should not happen */
}
return te[0];
}
struct Skynode*
mkskynode(void)
{
struct Skynode *h;
if((h=malloc(sizeof(struct Skynode)))==nil)
return nil;
memset(h, 0, sizeof(struct Skynode));
return h;
}
void*
findaddr(Rune *id, int *typ, int *dtyp)
{
struct Skynode *head;
Rune *t, tmp[Ltoksize+1];
head = cfg->head;
runestrncpy(tmp, id, Ltoksize+1);
tmp[Ltoksize] = L'\0';
DBPRINT(20, "cfg.c:findaddr %S ", id);
t = runestrtok(tmp, L".");
DBPRINT(20, "t=%S ", t);
if(!runestrcmp(t, L"obs")){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "obs. t=%S ", t);
if(!runestrcmp(t, L"g")){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "g. t=%S ", t);
*typ = Tdecimal;
*dtyp = DTdouble;
if(!runestrcmp(t, L"lat"))
return &cfg->obs.g.lat;
if(!runestrcmp(t, L"lng"))
return &cfg->obs.g.lng;
if(!runestrcmp(t, L"alt"))
return &cfg->obs.g.alt;
return nil;
}
return nil;
}
if(!runestrcmp(t, L"camera")){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "camera. t=%S ", t);
if(!runestrcmp(t, L"f")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &cfg->camera.f;
}
if(!runestrcmp(t, L"w")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &cfg->camera.w;
}
if(!runestrcmp(t, L"h")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &cfg->camera.h;
}
if(!runestrcmp(t, L"wpx")){
*typ = Tdecimal;
*dtyp = DTint;
return &cfg->camera.wpx;
}
if(!runestrcmp(t, L"hpx")){
*typ = Tdecimal;
*dtyp = DTint;
return &cfg->camera.hpx;
}
if(!runestrcmp(t, L"angle")){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "angle. t=%S ", t);
*typ = Tdecimal;
*dtyp = DTdouble;
if(!runestrcmp(t, L"az"))
return &cfg->camera.angle.az;
if(!runestrcmp(t, L"z"))
return &cfg->camera.angle.z;
if(!runestrcmp(t, L"roll"))
return &cfg->camera.angle.roll;
return nil;
}
return nil;
}
if(!runestrcmp(t, L"samplerate")){
*typ = Tdecimal;
*dtyp = DTint;
return &cfg->samplerate;
}
if(!runestrcmp(t, L"jd")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &cfg->jd;
}
if(!runestrcmp(t, L"atm")){
*typ = Tdecimal;
*dtyp = DTint;
return &cfg->atm;
}
/* is it an object identifier? (last one is always unset) */
while(head->next){
if(!runestrcmp(t, head->id)){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "node:%S. t=%S ", head->id, t);
if(!runestrcmp(t, L"str")){
*typ = Tstr;
*dtyp = DTstr;
return head->str;
}
if(!runestrcmp(t, L"eq")){
if((t = runestrtok(0, L".")) == 0) return nil;
DBPRINT(20, "gx. t=%S ", t);
*typ = Tdecimal;
*dtyp = DTdouble;
if(!runestrcmp(t, L"ra"))
return &head->eq.ra;
if(!runestrcmp(t, L"dec"))
return &head->eq.dec;
return nil;
}
if(!runestrcmp(t, L"bv")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &head->bv;
}
if(!runestrcmp(t, L"vmag")){
*typ = Tdecimal;
*dtyp = DTdouble;
return &head->vmag;
}
if(!runestrcmp(t, L"size")){
*typ = Tdecimal;
*dtyp = DTint;
return &head->size;
}
return nil;
}
head = head->next;
}
return nil;
}
|