⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scat.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <draw.h>#include <event.h>#include "sky.h"#include "strings.c"enum{	NNGC=7840,	/* number of NGC numbers [1..NNGC] */	NIC = 5386,	/* number of IC numbers */	NNGCrec=NNGC+NIC,	/* number of records in the NGC catalog (including IC's, starting at NNGC */	NMrec=122,	/* number of M records */	NM=110,		/* number of M numbers */	NAbell=2712,	/* number of records in the Abell catalog */	NName=1000,	/* number of prose names; estimated maximum (read from editable text file) */	NBayer=1517,	/* number of bayer entries */	NSAO=258998,	/* number of SAO stars */	MAXcon=1932,	/* maximum number of patches in a constellation */	Ncon=88,	/* number of constellations */	Npatch=92053,	/* highest patch number */};char		ngctype[NNGCrec];Mindexrec	mindex[NMrec];Namerec		name[NName];Bayerec		bayer[NBayer];long		con[MAXcon];ushort		conindex[Ncon+1];long		patchaddr[Npatch+1];Record	*rec;Record	*orec;Record	*cur;char	*dir=DIR;int	saodb;int	ngcdb;int	abelldb;int	ngctypedb;int	mindexdb;int	namedb;int	bayerdb;int	condb;int	conindexdb;int	patchdb;char	parsed[3];long	nrec;long	nreca;long	norec;long	noreca;Biobuf	bin;Biobuf	bout;main(int argc, char *argv[]){	char *line;	Binit(&bin, 0, OREAD);	Binit(&bout, 1, OWRITE);	if(argc != 1)		dir = argv[1];	astro("", 1);	while(line = Brdline(&bin, '\n')){		line[Blinelen(&bin)-1] = 0;		lookup(line, 1);		Bflush(&bout);	}	if(display != nil){		closedisplay(display);		/* automatic refresh of rio window is triggered by mouse */		close(open("/dev/mouse", OREAD));	}	return 0;}voidreset(void){	nrec = 0;	cur = rec;}voidgrow(void){	nrec++;	if(nreca < nrec){		nreca = nrec+50;		rec = realloc(rec, nreca*sizeof(Record));		if(rec == 0){			fprint(2, "scat: realloc fails\n");			exits("realloc");		}	}	cur = rec+nrec-1;}voidcopy(void){	if(noreca < nreca){		noreca = nreca;		orec = realloc(orec, nreca*sizeof(Record));		if(orec == 0){			fprint(2, "scat: realloc fails\n");			exits("realloc");		}	}	memmove(orec, rec, nrec*sizeof(Record));	norec = nrec;}inteopen(char *s){	char buf[128];	int f;	sprint(buf, "%s/%s.scat", dir, s);	f = open(buf, 0);	if(f<0){		fprint(2, "scat: can't open %s\n", buf);		exits("open");	}	return f;}voidEread(int f, char *name, void *addr, long n){	if(read(f, addr, n) != n){	/* BUG! */		fprint(2, "scat: read error on %s\n", name);		exits("read");	}}char*skipbl(char *s){	while(*s!=0 && (*s==' ' || *s=='\t'))		s++;	return s;}char*skipstr(char *s, char *t){	while(*s && *s==*t)		s++, t++;	return skipbl(s);}/* produce little-endian long at address l */longLong(long *l){	uchar *p;	p = (uchar*)l;	return (long)p[0]|((long)p[1]<<8)|((long)p[2]<<16)|((long)p[3]<<24);}/* produce little-endian long at address l */intShort(short *s){	uchar *p;	p = (uchar*)s;	return p[0]|(p[1]<<8);}voidnameopen(void){	Biobuf b;	int i;	char *l, *p;	if(namedb == 0){		namedb = eopen("name");		Binit(&b, namedb, OREAD);		for(i=0; i<NName; i++){			l = Brdline(&b, '\n');			if(l == 0)				break;			p = strchr(l, '\t');			if(p == 0){		Badformat:				Bprint(&bout, "warning: name.scat bad format; line %d\n", i+1);				break;			}			*p++ = 0;			strcpy(name[i].name, l);			if(strncmp(p, "ngc", 3) == 0)				name[i].ngc = atoi(p+3);			else if(strncmp(p, "ic", 2) == 0)				name[i].ngc = atoi(p+2)+NNGC;			else if(strncmp(p, "sao", 3) == 0)				name[i].sao = atoi(p+3);			else if(strncmp(p, "abell", 5) == 0)				name[i].abell = atoi(p+5);			else				goto Badformat;		}		if(i == NName)			Bprint(&bout, "warning: too many names in name.scat (max %d); extra ignored\n", NName);		close(namedb);		bayerdb = eopen("bayer");		Eread(bayerdb, "bayer", bayer, sizeof bayer);		close(bayerdb);		for(i=0; i<NBayer; i++)			bayer[i].sao = Long(&bayer[i].sao);	}}voidsaoopen(void){	if(saodb == 0){		nameopen();		saodb = eopen("sao");	}}voidngcopen(void){	if(ngcdb == 0){		nameopen();		ngcdb = eopen("ngc2000");		ngctypedb = eopen("ngc2000type");		Eread(ngctypedb, "ngctype", ngctype, sizeof ngctype);		close(ngctypedb);	}}voidabellopen(void){	/* nothing extra to do with abell: it's directly indexed by number */	if(abelldb == 0)		abelldb = eopen("abell");}voidpatchopen(void){	Biobuf *b;	long l, m;	char buf[100];	if(patchdb == 0){		patchdb = eopen("patch");		sprint(buf, "%s/patchindex.scat", dir);		b = Bopen(buf, OREAD);		if(b == 0){			fprint(2, "can't open %s\n", buf);			exits("open");		}		for(m=0,l=0; l<=Npatch; l++)			patchaddr[l] = m += Bgetc(b)*4;		Bterm(b);	}}voidmopen(void){	int i;	if(mindexdb == 0){		mindexdb = eopen("mindex");		Eread(mindexdb, "mindex", mindex, sizeof mindex);		close(mindexdb);		for(i=0; i<NMrec; i++)			mindex[i].ngc = Short(&mindex[i].ngc);	}}voidconstelopen(void){	int i;	if(condb == 0){		condb = eopen("con");		conindexdb = eopen("conindex");		Eread(conindexdb, "conindex", conindex, sizeof conindex);		close(conindexdb);		for(i=0; i<Ncon+1; i++)			conindex[i] = Short((short*)&conindex[i]);	}}voidlowercase(char *s){	for(; *s; s++)		if('A'<=*s && *s<='Z')			*s += 'a'-'A';}intloadngc(long index){	static int failed;	long j;	ngcopen();	j = (index-1)*sizeof(NGCrec);	grow();	cur->type = NGC;	cur->index = index;	seek(ngcdb, j, 0);	/* special case: NGC data may not be available */	if(read(ngcdb, &cur->ngc, sizeof(NGCrec)) != sizeof(NGCrec)){		if(!failed){			fprint(2, "scat: NGC database not available\n");			failed++;		}		cur->type = NONGC;		cur->ngc.ngc = 0;		cur->ngc.ra = 0;		cur->ngc.dec = 0;		cur->ngc.diam = 0;		cur->ngc.mag = 0;		return 0;	}	cur->ngc.ngc = Short(&cur->ngc.ngc);	cur->ngc.ra = Long(&cur->ngc.ra);	cur->ngc.dec = Long(&cur->ngc.dec);	cur->ngc.diam = Long(&cur->ngc.diam);	cur->ngc.mag = Short(&cur->ngc.mag);	return 1;}intloadabell(long index){	long j;	abellopen();	j = index-1;	grow();	cur->type = Abell;	cur->index = index;	seek(abelldb, j*sizeof(Abellrec), 0);	Eread(abelldb, "abell", &cur->abell, sizeof(Abellrec));	cur->abell.abell = Short(&cur->abell.abell);	if(cur->abell.abell != index){		fprint(2, "bad format in abell catalog\n");		exits("abell");	}	cur->abell.ra = Long(&cur->abell.ra);	cur->abell.dec = Long(&cur->abell.dec);	cur->abell.glat = Long(&cur->abell.glat);	cur->abell.glong = Long(&cur->abell.glong);	cur->abell.rad = Long(&cur->abell.rad);	cur->abell.mag10 = Short(&cur->abell.mag10);	cur->abell.pop = Short(&cur->abell.pop);	cur->abell.dist = Short(&cur->abell.dist);	return 1;}intloadsao(int index){	if(index<=0 || index>NSAO)		return 0;	saoopen();	grow();	cur->type = SAO;	cur->index = index;	seek(saodb, (index-1)*sizeof(SAOrec), 0);	Eread(saodb, "sao", &cur->sao, sizeof(SAOrec));	cur->sao.ra = Long(&cur->sao.ra);	cur->sao.dec = Long(&cur->sao.dec);	cur->sao.dra = Long(&cur->sao.dra);	cur->sao.ddec = Long(&cur->sao.ddec);	cur->sao.mag = Short(&cur->sao.mag);	cur->sao.mpg = Short(&cur->sao.mpg);	cur->sao.hd = Long(&cur->sao.hd);	return 1;}intloadplanet(int index, Record *r){	if(index<0 || index>NPlanet || planet[index].name[0]=='\0')		return 0;	grow();	cur->type = Planet;	cur->index = index;	/* check whether to take new or existing record */	if(r == nil)		memmove(&cur->planet, &planet[index], sizeof(Planetrec));	else		memmove(&cur->planet, &r->planet, sizeof(Planetrec));	return 1;}intloadpatch(long index){	int i;	patchopen();	if(index<=0 || index>Npatch)		return 0;	grow();	cur->type = Patch;	cur->index = index;	seek(patchdb, patchaddr[index-1], 0);	cur->patch.nkey = (patchaddr[index]-patchaddr[index-1])/4;	Eread(patchdb, "patch", cur->patch.key, cur->patch.nkey*4);	for(i=0; i<cur->patch.nkey; i++)		cur->patch.key[i] = Long(&cur->patch.key[i]);	return 1;}intloadtype(int t){	int i;	ngcopen();	for(i=0; i<NNGCrec; i++)		if(t == (ngctype[i])){			grow();			cur->type = NGCN;			cur->index = i+1;		}	return 1;}voidflatten(void){	int i, j, notflat;	Record *or;	long key;    loop:	copy();	reset();	notflat = 0;	for(i=0,or=orec; i<norec; i++,or++){		switch(or->type){		default:			fprint(2, "bad type %d in flatten\n", or->type);			break;		case NONGC:			break;		case Planet:		case Abell:		case NGC:		case SAO:			grow();			memmove(cur, or, sizeof(Record));			break;		case NGCN:			if(loadngc(or->index))				notflat = 1;			break;		case NamedSAO:			loadsao(or->index);			notflat = 1;			break;		case NamedNGC:			if(loadngc(or->index))				notflat = 1;			break;		case NamedAbell:			loadabell(or->index);			notflat = 1;			break;		case PatchC:			loadpatch(or->index);			notflat = 1;			break;		case Patch:			for(j=1; j<or->patch.nkey; j++){				key = or->patch.key[j];				if((key&0x3F) == SAO)					loadsao((key>>8)&0xFFFFFF);				else if((key&0x3F) == Abell)					loadabell((key>>8)&0xFFFFFF);				else					loadngc((key>>16)&0xFFFF);			}			break;		}	}	if(notflat)		goto loop;}intism(int index){	int i;	for(i=0; i<NMrec; i++)		if(mindex[i].ngc == index)			return 1;	return 0;}char*alpha(char *s, char *t){	int n;	n = strlen(t);	if(strncmp(s, t, n)==0 && (s[n]<'a' || 'z'<s[n]))		return skipbl(s+n);	return 0;	}char*text(char *s, char *t){	int n;	n = strlen(t);	if(strncmp(s, t, n)==0 && (s[n]==0 || s[n]==' ' || s[n]=='\t'))		return skipbl(s+n);	return 0;	}intcull(char *s, int keep, int dobbox){	int i, j, nobj, keepthis;	Record *or;	char *t;	int dogrtr, doless, dom, dosao, dongc, doabell;	int mgrtr, mless;	char obj[100];	memset(obj, 0, sizeof(obj));	nobj = 0;	dogrtr = 0;	doless = 0;	dom = 0;	dongc = 0;	dosao = 0;	doabell = 0;	mgrtr = mless= 0;	if(dobbox)		goto Cull;	for(;;){		if(s[0] == '>'){			dogrtr = 1;			mgrtr = 10 * strtod(s+1, &t);			if(mgrtr==0  && t==s+1){				fprint(2, "bad magnitude\n");				return 0;			}			s = skipbl(t);			continue;		}		if(s[0] == '<'){			doless = 1;			mless = 10 * strtod(s+1, &t);			if(mless==0  && t==s+1){				fprint(2, "bad magnitude\n");				return 0;			}			s = skipbl(t);			continue;		}		if(t = text(s, "m")){ 			dom = 1;			s = t;			continue;		}		if(t = text(s, "sao")){			dosao = 1;			s = t;			continue;		}		if(t = text(s, "ngc")){			dongc = 1;			s = t;			continue;		}		if(t = text(s, "abell")){			doabell = 1;			s = t;			continue;		}		for(i=0; names[i].name; i++)			if(t = alpha(s, names[i].name)){				if(nobj > 100){					fprint(2, "too many object types\n");					return 0;				}				obj[nobj++] = names[i].type;				s = t;				goto Continue;			}		break;	    Continue:;	}	if(*s){		fprint(2, "syntax error in object list\n");		return 0;	}    Cull:	flatten();	copy();	reset();	if(dom)		mopen();	if(dosao)		saoopen();	if(dongc || nobj)		ngcopen();	if(doabell)		abellopen();	for(i=0,or=orec; i<norec; i++,or++){		keepthis = !keep;		if(dobbox && inbbox(or->ngc.ra, or->ngc.dec))			keepthis = keep;		if(doless && or->ngc.mag <= mless)			keepthis = keep;		if(dogrtr && or->ngc.mag >= mgrtr)			keepthis = keep;		if(dom && (or->type==NGC && ism(or->ngc.ngc)))			keepthis = keep;		if(dongc && or->type==NGC)			keepthis = keep;		if(doabell && or->type==Abell)			keepthis = keep;		if(dosao && or->type==SAO)			keepthis = keep;		for(j=0; j<nobj; j++)			if(or->type==NGC && or->ngc.type==obj[j])				keepthis = keep;		if(keepthis){			grow();			memmove(cur, or, sizeof(Record));		}	}	return 1;}intcompar(void *va, void *vb){	Record *a=va, *b=vb;	if(a->type == b->type)		return a->index - b->index;	return a->type - b->type;}voidsort(void){	int i;	Record *r, *s;	if(nrec == 0)		return;	qsort(rec, nrec, sizeof(Record), compar);	r = rec+1;	s = rec;	for(i=1; i<nrec; i++,r++){		/* may have multiple instances of a planet in the scene */		if(r->type==s->type && r->index==s->index && r->type!=Planet)			continue;		memmove(++s, r, sizeof(Record));	}	nrec = (s+1)-rec;}char	greekbuf[128];char*togreek(char *s){	char *t;	int i, n;	Rune r;	t = greekbuf;	while(*s){		for(i=1; i<=24; i++){			n = strlen(greek[i]);			if(strncmp(s, greek[i], n)==0 && (s[n]==' ' || s[n]=='\t')){				s += n;				t += runetochar(t, &greeklet[i]);				goto Cont;			}		}		n = chartorune(&r, s);		for(i=0; i<n; i++)			*t++ = *s++;    Cont:;	}	*t = 0;	return greekbuf;}char*fromgreek(char *s){	char *t;	int i, n;	Rune r;	t = greekbuf;	while(*s){		n = chartorune(&r, s);		for(i=1; i<=24; i++){			if(r == greeklet[i]){				strcpy(t, greek[i]);				t += strlen(greek[i]);				s += n;				goto Cont;			}		}		for(i=0; i<n; i++)			*t++ = *s++;    Cont:;	}	*t = 0;	return greekbuf;}#ifdef OLD/* * Old version */intcoords(int deg){	int i;	int x, y;	Record *or;	long dec, ra, ndec, nra;	int rdeg;	flatten();	copy();	reset();	deg *= 2;	for(i=0,or=orec; i<norec; i++,or++){		if(or->type == Planet)	/* must keep it here */			loadplanet(or->index, or);		dec = or->ngc.dec/MILLIARCSEC;		ra = or->ngc.ra/MILLIARCSEC;		rdeg = deg/cos((dec*PI)/180);		for(y=-deg; y<=+deg; y++){			ndec = dec*2+y;			if(ndec/2>=90 || ndec/2<=-90)				continue;			/* fp errors hurt here, so we round 1' to the pole */			if(ndec >= 0)				ndec = ndec*500*60*60 + 60000;			else				ndec = ndec*500*60*60 - 60000;			for(x=-rdeg; x<=+rdeg; x++){				nra = ra*2+x;				if(nra/2 < 0)					nra += 360*2;				if(nra/2 >= 360)					nra -= 360*2;				/* fp errors hurt here, so we round up 1' */				nra = nra/2*MILLIARCSEC + 60000;				loadpatch(patcha(angle(nra), angle(ndec)));			}		}	}	sort();	return 1;}#endif/* * New version attempts to match the boundaries of the plot better. */intcoords(int deg){	int i;	int x, y, xx;	Record *or;	long min, circle;	double factor;	flatten();	circle = 360*MILLIARCSEC;	deg *= MILLIARCSEC;	/* find center */	folded = 0;	bbox(0, 0, 0);	/* now expand */	factor = cos(angle((decmax+decmin)/2));	if(factor < .2)		factor = .2;	factor = floor(1/factor);	folded = 0;	bbox(factor*deg, deg, 1);	Bprint(&bout, "%s to ", hms(angle(ramin)));	Bprint(&bout, "%s\n", hms(angle(ramax)));	Bprint(&bout, "%s to ", dms(angle(decmin)));	Bprint(&bout, "%s\n", dms(angle(decmax)));	copy();	reset();	for(i=0,or=orec; i<norec; i++,or++)		if(or->type == Planet)	/* must keep it here */			loadplanet(or->index, or);	min = ramin;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -