Plan 9 from Bell Labs’s /usr/web/sources/contrib/pdt/sky/cmd/skywatch/cfg.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#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;
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].