xref: /plan9/sys/src/cmd/scat/scat.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <draw.h>
57dd7cddfSDavid du Colombier #include <event.h>
63e12c5d1SDavid du Colombier #include "sky.h"
73e12c5d1SDavid du Colombier #include "strings.c"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier enum
103e12c5d1SDavid du Colombier {
11219b2ee8SDavid du Colombier 	NNGC=7840,	/* number of NGC numbers [1..NNGC] */
12219b2ee8SDavid du Colombier 	NIC = 5386,	/* number of IC numbers */
13219b2ee8SDavid du Colombier 	NNGCrec=NNGC+NIC,	/* number of records in the NGC catalog (including IC's, starting at NNGC */
14219b2ee8SDavid du Colombier 	NMrec=122,	/* number of M records */
153e12c5d1SDavid du Colombier 	NM=110,		/* number of M numbers */
16219b2ee8SDavid du Colombier 	NAbell=2712,	/* number of records in the Abell catalog */
17219b2ee8SDavid du Colombier 	NName=1000,	/* number of prose names; estimated maximum (read from editable text file) */
183e12c5d1SDavid du Colombier 	NBayer=1517,	/* number of bayer entries */
193e12c5d1SDavid du Colombier 	NSAO=258998,	/* number of SAO stars */
203e12c5d1SDavid du Colombier 	MAXcon=1932,	/* maximum number of patches in a constellation */
213e12c5d1SDavid du Colombier 	Ncon=88,	/* number of constellations */
223e12c5d1SDavid du Colombier 	Npatch=92053,	/* highest patch number */
233e12c5d1SDavid du Colombier };
243e12c5d1SDavid du Colombier 
25219b2ee8SDavid du Colombier char		ngctype[NNGCrec];
26219b2ee8SDavid du Colombier Mindexrec	mindex[NMrec];
273e12c5d1SDavid du Colombier Namerec		name[NName];
283e12c5d1SDavid du Colombier Bayerec		bayer[NBayer];
293e12c5d1SDavid du Colombier long		con[MAXcon];
303e12c5d1SDavid du Colombier ushort		conindex[Ncon+1];
313e12c5d1SDavid du Colombier long		patchaddr[Npatch+1];
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier Record	*rec;
343e12c5d1SDavid du Colombier Record	*orec;
353e12c5d1SDavid du Colombier Record	*cur;
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier char	*dir=DIR;
383e12c5d1SDavid du Colombier int	saodb;
393e12c5d1SDavid du Colombier int	ngcdb;
40219b2ee8SDavid du Colombier int	abelldb;
41219b2ee8SDavid du Colombier int	ngctypedb;
423e12c5d1SDavid du Colombier int	mindexdb;
433e12c5d1SDavid du Colombier int	namedb;
443e12c5d1SDavid du Colombier int	bayerdb;
453e12c5d1SDavid du Colombier int	condb;
463e12c5d1SDavid du Colombier int	conindexdb;
473e12c5d1SDavid du Colombier int	patchdb;
483e12c5d1SDavid du Colombier char	parsed[3];
493e12c5d1SDavid du Colombier long	nrec;
503e12c5d1SDavid du Colombier long	nreca;
513e12c5d1SDavid du Colombier long	norec;
523e12c5d1SDavid du Colombier long	noreca;
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier Biobuf	bin;
553e12c5d1SDavid du Colombier Biobuf	bout;
563e12c5d1SDavid du Colombier 
main(int argc,char * argv[])573e12c5d1SDavid du Colombier main(int argc, char *argv[])
583e12c5d1SDavid du Colombier {
593e12c5d1SDavid du Colombier 	char *line;
603e12c5d1SDavid du Colombier 
613e12c5d1SDavid du Colombier 	Binit(&bin, 0, OREAD);
623e12c5d1SDavid du Colombier 	Binit(&bout, 1, OWRITE);
633e12c5d1SDavid du Colombier 	if(argc != 1)
643e12c5d1SDavid du Colombier 		dir = argv[1];
6559cc4ca5SDavid du Colombier 	astro("", 1);
663e12c5d1SDavid du Colombier 	while(line = Brdline(&bin, '\n')){
677dd7cddfSDavid du Colombier 		line[Blinelen(&bin)-1] = 0;
683e12c5d1SDavid du Colombier 		lookup(line, 1);
693e12c5d1SDavid du Colombier 		Bflush(&bout);
703e12c5d1SDavid du Colombier 	}
717dd7cddfSDavid du Colombier 	if(display != nil){
727dd7cddfSDavid du Colombier 		closedisplay(display);
737dd7cddfSDavid du Colombier 		/* automatic refresh of rio window is triggered by mouse */
747dd7cddfSDavid du Colombier 		close(open("/dev/mouse", OREAD));
757dd7cddfSDavid du Colombier 	}
763e12c5d1SDavid du Colombier 	return 0;
773e12c5d1SDavid du Colombier }
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier void
reset(void)803e12c5d1SDavid du Colombier reset(void)
813e12c5d1SDavid du Colombier {
823e12c5d1SDavid du Colombier 	nrec = 0;
833e12c5d1SDavid du Colombier 	cur = rec;
843e12c5d1SDavid du Colombier }
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier void
grow(void)873e12c5d1SDavid du Colombier grow(void)
883e12c5d1SDavid du Colombier {
893e12c5d1SDavid du Colombier 	nrec++;
903e12c5d1SDavid du Colombier 	if(nreca < nrec){
913e12c5d1SDavid du Colombier 		nreca = nrec+50;
923e12c5d1SDavid du Colombier 		rec = realloc(rec, nreca*sizeof(Record));
933e12c5d1SDavid du Colombier 		if(rec == 0){
943e12c5d1SDavid du Colombier 			fprint(2, "scat: realloc fails\n");
953e12c5d1SDavid du Colombier 			exits("realloc");
963e12c5d1SDavid du Colombier 		}
973e12c5d1SDavid du Colombier 	}
983e12c5d1SDavid du Colombier 	cur = rec+nrec-1;
993e12c5d1SDavid du Colombier }
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier void
copy(void)1023e12c5d1SDavid du Colombier copy(void)
1033e12c5d1SDavid du Colombier {
1043e12c5d1SDavid du Colombier 	if(noreca < nreca){
1053e12c5d1SDavid du Colombier 		noreca = nreca;
1063e12c5d1SDavid du Colombier 		orec = realloc(orec, nreca*sizeof(Record));
1073e12c5d1SDavid du Colombier 		if(orec == 0){
1083e12c5d1SDavid du Colombier 			fprint(2, "scat: realloc fails\n");
1093e12c5d1SDavid du Colombier 			exits("realloc");
1103e12c5d1SDavid du Colombier 		}
1113e12c5d1SDavid du Colombier 	}
1123e12c5d1SDavid du Colombier 	memmove(orec, rec, nrec*sizeof(Record));
1133e12c5d1SDavid du Colombier 	norec = nrec;
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier int
eopen(char * s)1173e12c5d1SDavid du Colombier eopen(char *s)
1183e12c5d1SDavid du Colombier {
1193e12c5d1SDavid du Colombier 	char buf[128];
1203e12c5d1SDavid du Colombier 	int f;
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier 	sprint(buf, "%s/%s.scat", dir, s);
1233e12c5d1SDavid du Colombier 	f = open(buf, 0);
1243e12c5d1SDavid du Colombier 	if(f<0){
1253e12c5d1SDavid du Colombier 		fprint(2, "scat: can't open %s\n", buf);
1263e12c5d1SDavid du Colombier 		exits("open");
1273e12c5d1SDavid du Colombier 	}
1283e12c5d1SDavid du Colombier 	return f;
1293e12c5d1SDavid du Colombier }
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier 
1323e12c5d1SDavid du Colombier void
Eread(int f,char * name,void * addr,long n)1333e12c5d1SDavid du Colombier Eread(int f, char *name, void *addr, long n)
1343e12c5d1SDavid du Colombier {
1353e12c5d1SDavid du Colombier 	if(read(f, addr, n) != n){	/* BUG! */
1363e12c5d1SDavid du Colombier 		fprint(2, "scat: read error on %s\n", name);
1373e12c5d1SDavid du Colombier 		exits("read");
1383e12c5d1SDavid du Colombier 	}
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier char*
skipbl(char * s)1423e12c5d1SDavid du Colombier skipbl(char *s)
1433e12c5d1SDavid du Colombier {
1443e12c5d1SDavid du Colombier 	while(*s!=0 && (*s==' ' || *s=='\t'))
1453e12c5d1SDavid du Colombier 		s++;
1463e12c5d1SDavid du Colombier 	return s;
1473e12c5d1SDavid du Colombier }
1483e12c5d1SDavid du Colombier 
1493e12c5d1SDavid du Colombier char*
skipstr(char * s,char * t)1503e12c5d1SDavid du Colombier skipstr(char *s, char *t)
1513e12c5d1SDavid du Colombier {
1523e12c5d1SDavid du Colombier 	while(*s && *s==*t)
1533e12c5d1SDavid du Colombier 		s++, t++;
1543e12c5d1SDavid du Colombier 	return skipbl(s);
1553e12c5d1SDavid du Colombier }
1563e12c5d1SDavid du Colombier 
1573e12c5d1SDavid du Colombier /* produce little-endian long at address l */
1583e12c5d1SDavid du Colombier long
Long(long * l)1593e12c5d1SDavid du Colombier Long(long *l)
1603e12c5d1SDavid du Colombier {
1613e12c5d1SDavid du Colombier 	uchar *p;
1623e12c5d1SDavid du Colombier 
1633e12c5d1SDavid du Colombier 	p = (uchar*)l;
1643e12c5d1SDavid du Colombier 	return (long)p[0]|((long)p[1]<<8)|((long)p[2]<<16)|((long)p[3]<<24);
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier 
1673e12c5d1SDavid du Colombier /* produce little-endian long at address l */
1683e12c5d1SDavid du Colombier int
Short(short * s)1693e12c5d1SDavid du Colombier Short(short *s)
1703e12c5d1SDavid du Colombier {
1713e12c5d1SDavid du Colombier 	uchar *p;
1723e12c5d1SDavid du Colombier 
1733e12c5d1SDavid du Colombier 	p = (uchar*)s;
1743e12c5d1SDavid du Colombier 	return p[0]|(p[1]<<8);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier void
nameopen(void)178219b2ee8SDavid du Colombier nameopen(void)
1793e12c5d1SDavid du Colombier {
180219b2ee8SDavid du Colombier 	Biobuf b;
181219b2ee8SDavid du Colombier 	int i;
182219b2ee8SDavid du Colombier 	char *l, *p;
1833e12c5d1SDavid du Colombier 
184219b2ee8SDavid du Colombier 	if(namedb == 0){
1853e12c5d1SDavid du Colombier 		namedb = eopen("name");
186219b2ee8SDavid du Colombier 		Binit(&b, namedb, OREAD);
187219b2ee8SDavid du Colombier 		for(i=0; i<NName; i++){
188219b2ee8SDavid du Colombier 			l = Brdline(&b, '\n');
189219b2ee8SDavid du Colombier 			if(l == 0)
190219b2ee8SDavid du Colombier 				break;
191219b2ee8SDavid du Colombier 			p = strchr(l, '\t');
192219b2ee8SDavid du Colombier 			if(p == 0){
193219b2ee8SDavid du Colombier 		Badformat:
194219b2ee8SDavid du Colombier 				Bprint(&bout, "warning: name.scat bad format; line %d\n", i+1);
195219b2ee8SDavid du Colombier 				break;
196219b2ee8SDavid du Colombier 			}
197219b2ee8SDavid du Colombier 			*p++ = 0;
198219b2ee8SDavid du Colombier 			strcpy(name[i].name, l);
199219b2ee8SDavid du Colombier 			if(strncmp(p, "ngc", 3) == 0)
200219b2ee8SDavid du Colombier 				name[i].ngc = atoi(p+3);
201219b2ee8SDavid du Colombier 			else if(strncmp(p, "ic", 2) == 0)
202219b2ee8SDavid du Colombier 				name[i].ngc = atoi(p+2)+NNGC;
203219b2ee8SDavid du Colombier 			else if(strncmp(p, "sao", 3) == 0)
204219b2ee8SDavid du Colombier 				name[i].sao = atoi(p+3);
205219b2ee8SDavid du Colombier 			else if(strncmp(p, "abell", 5) == 0)
206219b2ee8SDavid du Colombier 				name[i].abell = atoi(p+5);
207219b2ee8SDavid du Colombier 			else
208219b2ee8SDavid du Colombier 				goto Badformat;
209219b2ee8SDavid du Colombier 		}
210219b2ee8SDavid du Colombier 		if(i == NName)
211219b2ee8SDavid du Colombier 			Bprint(&bout, "warning: too many names in name.scat (max %d); extra ignored\n", NName);
2123e12c5d1SDavid du Colombier 		close(namedb);
2133e12c5d1SDavid du Colombier 
2143e12c5d1SDavid du Colombier 		bayerdb = eopen("bayer");
2153e12c5d1SDavid du Colombier 		Eread(bayerdb, "bayer", bayer, sizeof bayer);
2163e12c5d1SDavid du Colombier 		close(bayerdb);
2173e12c5d1SDavid du Colombier 		for(i=0; i<NBayer; i++)
2183e12c5d1SDavid du Colombier 			bayer[i].sao = Long(&bayer[i].sao);
2193e12c5d1SDavid du Colombier 	}
2203e12c5d1SDavid du Colombier }
2213e12c5d1SDavid du Colombier 
2223e12c5d1SDavid du Colombier void
saoopen(void)223219b2ee8SDavid du Colombier saoopen(void)
224219b2ee8SDavid du Colombier {
225219b2ee8SDavid du Colombier 	if(saodb == 0){
226219b2ee8SDavid du Colombier 		nameopen();
227219b2ee8SDavid du Colombier 		saodb = eopen("sao");
228219b2ee8SDavid du Colombier 	}
229219b2ee8SDavid du Colombier }
230219b2ee8SDavid du Colombier 
231219b2ee8SDavid du Colombier void
ngcopen(void)2323e12c5d1SDavid du Colombier ngcopen(void)
2333e12c5d1SDavid du Colombier {
2343e12c5d1SDavid du Colombier 	if(ngcdb == 0){
235219b2ee8SDavid du Colombier 		nameopen();
236219b2ee8SDavid du Colombier 		ngcdb = eopen("ngc2000");
237219b2ee8SDavid du Colombier 		ngctypedb = eopen("ngc2000type");
238219b2ee8SDavid du Colombier 		Eread(ngctypedb, "ngctype", ngctype, sizeof ngctype);
239219b2ee8SDavid du Colombier 		close(ngctypedb);
2403e12c5d1SDavid du Colombier 	}
2413e12c5d1SDavid du Colombier }
2423e12c5d1SDavid du Colombier 
2433e12c5d1SDavid du Colombier void
abellopen(void)244219b2ee8SDavid du Colombier abellopen(void)
245219b2ee8SDavid du Colombier {
246219b2ee8SDavid du Colombier 	/* nothing extra to do with abell: it's directly indexed by number */
247219b2ee8SDavid du Colombier 	if(abelldb == 0)
248219b2ee8SDavid du Colombier 		abelldb = eopen("abell");
249219b2ee8SDavid du Colombier }
250219b2ee8SDavid du Colombier 
251219b2ee8SDavid du Colombier void
patchopen(void)2523e12c5d1SDavid du Colombier patchopen(void)
2533e12c5d1SDavid du Colombier {
2543e12c5d1SDavid du Colombier 	Biobuf *b;
2553e12c5d1SDavid du Colombier 	long l, m;
2563e12c5d1SDavid du Colombier 	char buf[100];
2573e12c5d1SDavid du Colombier 
2583e12c5d1SDavid du Colombier 	if(patchdb == 0){
2593e12c5d1SDavid du Colombier 		patchdb = eopen("patch");
2603e12c5d1SDavid du Colombier 		sprint(buf, "%s/patchindex.scat", dir);
2613e12c5d1SDavid du Colombier 		b = Bopen(buf, OREAD);
2623e12c5d1SDavid du Colombier 		if(b == 0){
2633e12c5d1SDavid du Colombier 			fprint(2, "can't open %s\n", buf);
2643e12c5d1SDavid du Colombier 			exits("open");
2653e12c5d1SDavid du Colombier 		}
2663e12c5d1SDavid du Colombier 		for(m=0,l=0; l<=Npatch; l++)
2673e12c5d1SDavid du Colombier 			patchaddr[l] = m += Bgetc(b)*4;
268219b2ee8SDavid du Colombier 		Bterm(b);
2693e12c5d1SDavid du Colombier 	}
2703e12c5d1SDavid du Colombier }
2713e12c5d1SDavid du Colombier 
2723e12c5d1SDavid du Colombier void
mopen(void)2733e12c5d1SDavid du Colombier mopen(void)
2743e12c5d1SDavid du Colombier {
2753e12c5d1SDavid du Colombier 	int i;
2763e12c5d1SDavid du Colombier 
2773e12c5d1SDavid du Colombier 	if(mindexdb == 0){
2783e12c5d1SDavid du Colombier 		mindexdb = eopen("mindex");
2793e12c5d1SDavid du Colombier 		Eread(mindexdb, "mindex", mindex, sizeof mindex);
2803e12c5d1SDavid du Colombier 		close(mindexdb);
2813e12c5d1SDavid du Colombier 		for(i=0; i<NMrec; i++)
2823e12c5d1SDavid du Colombier 			mindex[i].ngc = Short(&mindex[i].ngc);
2833e12c5d1SDavid du Colombier 	}
2843e12c5d1SDavid du Colombier }
2853e12c5d1SDavid du Colombier 
2863e12c5d1SDavid du Colombier void
constelopen(void)2873e12c5d1SDavid du Colombier constelopen(void)
2883e12c5d1SDavid du Colombier {
2893e12c5d1SDavid du Colombier 	int i;
2903e12c5d1SDavid du Colombier 
2913e12c5d1SDavid du Colombier 	if(condb == 0){
2923e12c5d1SDavid du Colombier 		condb = eopen("con");
2933e12c5d1SDavid du Colombier 		conindexdb = eopen("conindex");
2943e12c5d1SDavid du Colombier 		Eread(conindexdb, "conindex", conindex, sizeof conindex);
2953e12c5d1SDavid du Colombier 		close(conindexdb);
2963e12c5d1SDavid du Colombier 		for(i=0; i<Ncon+1; i++)
2973e12c5d1SDavid du Colombier 			conindex[i] = Short((short*)&conindex[i]);
2983e12c5d1SDavid du Colombier 	}
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier 
3013e12c5d1SDavid du Colombier void
lowercase(char * s)3023e12c5d1SDavid du Colombier lowercase(char *s)
3033e12c5d1SDavid du Colombier {
3043e12c5d1SDavid du Colombier 	for(; *s; s++)
3053e12c5d1SDavid du Colombier 		if('A'<=*s && *s<='Z')
3063e12c5d1SDavid du Colombier 			*s += 'a'-'A';
3073e12c5d1SDavid du Colombier }
3083e12c5d1SDavid du Colombier 
3093e12c5d1SDavid du Colombier int
loadngc(long index)310219b2ee8SDavid du Colombier loadngc(long index)
3113e12c5d1SDavid du Colombier {
3127dd7cddfSDavid du Colombier 	static int failed;
3133e12c5d1SDavid du Colombier 	long j;
3143e12c5d1SDavid du Colombier 
3153e12c5d1SDavid du Colombier 	ngcopen();
316219b2ee8SDavid du Colombier 	j = (index-1)*sizeof(NGCrec);
3173e12c5d1SDavid du Colombier 	grow();
3183e12c5d1SDavid du Colombier 	cur->type = NGC;
3193e12c5d1SDavid du Colombier 	cur->index = index;
320219b2ee8SDavid du Colombier 	seek(ngcdb, j, 0);
3217dd7cddfSDavid du Colombier 	/* special case: NGC data may not be available */
3227dd7cddfSDavid du Colombier 	if(read(ngcdb, &cur->ngc, sizeof(NGCrec)) != sizeof(NGCrec)){
3237dd7cddfSDavid du Colombier 		if(!failed){
3247dd7cddfSDavid du Colombier 			fprint(2, "scat: NGC database not available\n");
3257dd7cddfSDavid du Colombier 			failed++;
3267dd7cddfSDavid du Colombier 		}
3277dd7cddfSDavid du Colombier 		cur->type = NONGC;
3287dd7cddfSDavid du Colombier 		cur->ngc.ngc = 0;
3297dd7cddfSDavid du Colombier 		cur->ngc.ra = 0;
3307dd7cddfSDavid du Colombier 		cur->ngc.dec = 0;
3317dd7cddfSDavid du Colombier 		cur->ngc.diam = 0;
3327dd7cddfSDavid du Colombier 		cur->ngc.mag = 0;
3337dd7cddfSDavid du Colombier 		return 0;
3347dd7cddfSDavid du Colombier 	}
3353e12c5d1SDavid du Colombier 	cur->ngc.ngc = Short(&cur->ngc.ngc);
3363e12c5d1SDavid du Colombier 	cur->ngc.ra = Long(&cur->ngc.ra);
3373e12c5d1SDavid du Colombier 	cur->ngc.dec = Long(&cur->ngc.dec);
338219b2ee8SDavid du Colombier 	cur->ngc.diam = Long(&cur->ngc.diam);
3393e12c5d1SDavid du Colombier 	cur->ngc.mag = Short(&cur->ngc.mag);
3403e12c5d1SDavid du Colombier 	return 1;
3413e12c5d1SDavid du Colombier }
3423e12c5d1SDavid du Colombier 
3433e12c5d1SDavid du Colombier int
loadabell(long index)344219b2ee8SDavid du Colombier loadabell(long index)
345219b2ee8SDavid du Colombier {
346219b2ee8SDavid du Colombier 	long j;
347219b2ee8SDavid du Colombier 
348219b2ee8SDavid du Colombier 	abellopen();
349219b2ee8SDavid du Colombier 	j = index-1;
350219b2ee8SDavid du Colombier 	grow();
351219b2ee8SDavid du Colombier 	cur->type = Abell;
352219b2ee8SDavid du Colombier 	cur->index = index;
353219b2ee8SDavid du Colombier 	seek(abelldb, j*sizeof(Abellrec), 0);
354219b2ee8SDavid du Colombier 	Eread(abelldb, "abell", &cur->abell, sizeof(Abellrec));
355219b2ee8SDavid du Colombier 	cur->abell.abell = Short(&cur->abell.abell);
356219b2ee8SDavid du Colombier 	if(cur->abell.abell != index){
357219b2ee8SDavid du Colombier 		fprint(2, "bad format in abell catalog\n");
358219b2ee8SDavid du Colombier 		exits("abell");
359219b2ee8SDavid du Colombier 	}
360219b2ee8SDavid du Colombier 	cur->abell.ra = Long(&cur->abell.ra);
361219b2ee8SDavid du Colombier 	cur->abell.dec = Long(&cur->abell.dec);
362219b2ee8SDavid du Colombier 	cur->abell.glat = Long(&cur->abell.glat);
363219b2ee8SDavid du Colombier 	cur->abell.glong = Long(&cur->abell.glong);
364219b2ee8SDavid du Colombier 	cur->abell.rad = Long(&cur->abell.rad);
365219b2ee8SDavid du Colombier 	cur->abell.mag10 = Short(&cur->abell.mag10);
366219b2ee8SDavid du Colombier 	cur->abell.pop = Short(&cur->abell.pop);
367219b2ee8SDavid du Colombier 	cur->abell.dist = Short(&cur->abell.dist);
368219b2ee8SDavid du Colombier 	return 1;
369219b2ee8SDavid du Colombier }
370219b2ee8SDavid du Colombier 
371219b2ee8SDavid du Colombier int
loadsao(int index)3723e12c5d1SDavid du Colombier loadsao(int index)
3733e12c5d1SDavid du Colombier {
3743e12c5d1SDavid du Colombier 	if(index<=0 || index>NSAO)
3753e12c5d1SDavid du Colombier 		return 0;
3763e12c5d1SDavid du Colombier 	saoopen();
3773e12c5d1SDavid du Colombier 	grow();
3783e12c5d1SDavid du Colombier 	cur->type = SAO;
3793e12c5d1SDavid du Colombier 	cur->index = index;
3803e12c5d1SDavid du Colombier 	seek(saodb, (index-1)*sizeof(SAOrec), 0);
3813e12c5d1SDavid du Colombier 	Eread(saodb, "sao", &cur->sao, sizeof(SAOrec));
3823e12c5d1SDavid du Colombier 	cur->sao.ra = Long(&cur->sao.ra);
3833e12c5d1SDavid du Colombier 	cur->sao.dec = Long(&cur->sao.dec);
3843e12c5d1SDavid du Colombier 	cur->sao.dra = Long(&cur->sao.dra);
3853e12c5d1SDavid du Colombier 	cur->sao.ddec = Long(&cur->sao.ddec);
3863e12c5d1SDavid du Colombier 	cur->sao.mag = Short(&cur->sao.mag);
3873e12c5d1SDavid du Colombier 	cur->sao.mpg = Short(&cur->sao.mpg);
3883e12c5d1SDavid du Colombier 	cur->sao.hd = Long(&cur->sao.hd);
3893e12c5d1SDavid du Colombier 	return 1;
3903e12c5d1SDavid du Colombier }
3913e12c5d1SDavid du Colombier 
3923e12c5d1SDavid du Colombier int
loadplanet(int index,Record * r)39359cc4ca5SDavid du Colombier loadplanet(int index, Record *r)
39459cc4ca5SDavid du Colombier {
39559cc4ca5SDavid du Colombier 	if(index<0 || index>NPlanet || planet[index].name[0]=='\0')
39659cc4ca5SDavid du Colombier 		return 0;
39759cc4ca5SDavid du Colombier 	grow();
39859cc4ca5SDavid du Colombier 	cur->type = Planet;
39959cc4ca5SDavid du Colombier 	cur->index = index;
40059cc4ca5SDavid du Colombier 	/* check whether to take new or existing record */
40159cc4ca5SDavid du Colombier 	if(r == nil)
40259cc4ca5SDavid du Colombier 		memmove(&cur->planet, &planet[index], sizeof(Planetrec));
40359cc4ca5SDavid du Colombier 	else
40459cc4ca5SDavid du Colombier 		memmove(&cur->planet, &r->planet, sizeof(Planetrec));
40559cc4ca5SDavid du Colombier 	return 1;
40659cc4ca5SDavid du Colombier }
40759cc4ca5SDavid du Colombier 
40859cc4ca5SDavid du Colombier int
loadpatch(long index)4093e12c5d1SDavid du Colombier loadpatch(long index)
4103e12c5d1SDavid du Colombier {
4113e12c5d1SDavid du Colombier 	int i;
4123e12c5d1SDavid du Colombier 
4133e12c5d1SDavid du Colombier 	patchopen();
4143e12c5d1SDavid du Colombier 	if(index<=0 || index>Npatch)
4153e12c5d1SDavid du Colombier 		return 0;
4163e12c5d1SDavid du Colombier 	grow();
4173e12c5d1SDavid du Colombier 	cur->type = Patch;
4183e12c5d1SDavid du Colombier 	cur->index = index;
4193e12c5d1SDavid du Colombier 	seek(patchdb, patchaddr[index-1], 0);
4203e12c5d1SDavid du Colombier 	cur->patch.nkey = (patchaddr[index]-patchaddr[index-1])/4;
4213e12c5d1SDavid du Colombier 	Eread(patchdb, "patch", cur->patch.key, cur->patch.nkey*4);
4223e12c5d1SDavid du Colombier 	for(i=0; i<cur->patch.nkey; i++)
4233e12c5d1SDavid du Colombier 		cur->patch.key[i] = Long(&cur->patch.key[i]);
4243e12c5d1SDavid du Colombier 	return 1;
4253e12c5d1SDavid du Colombier }
4263e12c5d1SDavid du Colombier 
4273e12c5d1SDavid du Colombier int
loadtype(int t)4283e12c5d1SDavid du Colombier loadtype(int t)
4293e12c5d1SDavid du Colombier {
4303e12c5d1SDavid du Colombier 	int i;
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier 	ngcopen();
4333e12c5d1SDavid du Colombier 	for(i=0; i<NNGCrec; i++)
434219b2ee8SDavid du Colombier 		if(t == (ngctype[i])){
4353e12c5d1SDavid du Colombier 			grow();
4363e12c5d1SDavid du Colombier 			cur->type = NGCN;
437219b2ee8SDavid du Colombier 			cur->index = i+1;
4383e12c5d1SDavid du Colombier 		}
4393e12c5d1SDavid du Colombier 	return 1;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier 
4423e12c5d1SDavid du Colombier void
flatten(void)4433e12c5d1SDavid du Colombier flatten(void)
4443e12c5d1SDavid du Colombier {
4453e12c5d1SDavid du Colombier 	int i, j, notflat;
4463e12c5d1SDavid du Colombier 	Record *or;
4473e12c5d1SDavid du Colombier 	long key;
4483e12c5d1SDavid du Colombier 
4493e12c5d1SDavid du Colombier     loop:
4503e12c5d1SDavid du Colombier 	copy();
4513e12c5d1SDavid du Colombier 	reset();
4523e12c5d1SDavid du Colombier 	notflat = 0;
4533e12c5d1SDavid du Colombier 	for(i=0,or=orec; i<norec; i++,or++){
4543e12c5d1SDavid du Colombier 		switch(or->type){
4553e12c5d1SDavid du Colombier 		default:
456219b2ee8SDavid du Colombier 			fprint(2, "bad type %d in flatten\n", or->type);
4573e12c5d1SDavid du Colombier 			break;
4583e12c5d1SDavid du Colombier 
4597dd7cddfSDavid du Colombier 		case NONGC:
4607dd7cddfSDavid du Colombier 			break;
4617dd7cddfSDavid du Colombier 
46259cc4ca5SDavid du Colombier 		case Planet:
463219b2ee8SDavid du Colombier 		case Abell:
4643e12c5d1SDavid du Colombier 		case NGC:
4653e12c5d1SDavid du Colombier 		case SAO:
4663e12c5d1SDavid du Colombier 			grow();
4673e12c5d1SDavid du Colombier 			memmove(cur, or, sizeof(Record));
4683e12c5d1SDavid du Colombier 			break;
4693e12c5d1SDavid du Colombier 
4703e12c5d1SDavid du Colombier 		case NGCN:
4717dd7cddfSDavid du Colombier 			if(loadngc(or->index))
4723e12c5d1SDavid du Colombier 				notflat = 1;
4733e12c5d1SDavid du Colombier 			break;
4743e12c5d1SDavid du Colombier 
475219b2ee8SDavid du Colombier 		case NamedSAO:
4763e12c5d1SDavid du Colombier 			loadsao(or->index);
4773e12c5d1SDavid du Colombier 			notflat = 1;
4783e12c5d1SDavid du Colombier 			break;
4793e12c5d1SDavid du Colombier 
480219b2ee8SDavid du Colombier 		case NamedNGC:
4817dd7cddfSDavid du Colombier 			if(loadngc(or->index))
482219b2ee8SDavid du Colombier 				notflat = 1;
483219b2ee8SDavid du Colombier 			break;
484219b2ee8SDavid du Colombier 
485219b2ee8SDavid du Colombier 		case NamedAbell:
486219b2ee8SDavid du Colombier 			loadabell(or->index);
487219b2ee8SDavid du Colombier 			notflat = 1;
488219b2ee8SDavid du Colombier 			break;
489219b2ee8SDavid du Colombier 
4903e12c5d1SDavid du Colombier 		case PatchC:
4913e12c5d1SDavid du Colombier 			loadpatch(or->index);
4923e12c5d1SDavid du Colombier 			notflat = 1;
4933e12c5d1SDavid du Colombier 			break;
4943e12c5d1SDavid du Colombier 
4953e12c5d1SDavid du Colombier 		case Patch:
4963e12c5d1SDavid du Colombier 			for(j=1; j<or->patch.nkey; j++){
4973e12c5d1SDavid du Colombier 				key = or->patch.key[j];
4983e12c5d1SDavid du Colombier 				if((key&0x3F) == SAO)
4993e12c5d1SDavid du Colombier 					loadsao((key>>8)&0xFFFFFF);
500219b2ee8SDavid du Colombier 				else if((key&0x3F) == Abell)
501219b2ee8SDavid du Colombier 					loadabell((key>>8)&0xFFFFFF);
5023e12c5d1SDavid du Colombier 				else
503219b2ee8SDavid du Colombier 					loadngc((key>>16)&0xFFFF);
5043e12c5d1SDavid du Colombier 			}
5053e12c5d1SDavid du Colombier 			break;
5063e12c5d1SDavid du Colombier 		}
5073e12c5d1SDavid du Colombier 	}
5083e12c5d1SDavid du Colombier 	if(notflat)
5093e12c5d1SDavid du Colombier 		goto loop;
5103e12c5d1SDavid du Colombier }
5113e12c5d1SDavid du Colombier 
5123e12c5d1SDavid du Colombier int
ism(int index)5133e12c5d1SDavid du Colombier ism(int index)
5143e12c5d1SDavid du Colombier {
5153e12c5d1SDavid du Colombier 	int i;
5163e12c5d1SDavid du Colombier 
5173e12c5d1SDavid du Colombier 	for(i=0; i<NMrec; i++)
5183e12c5d1SDavid du Colombier 		if(mindex[i].ngc == index)
5193e12c5d1SDavid du Colombier 			return 1;
5203e12c5d1SDavid du Colombier 	return 0;
5213e12c5d1SDavid du Colombier }
5223e12c5d1SDavid du Colombier 
5233e12c5d1SDavid du Colombier char*
alpha(char * s,char * t)5243e12c5d1SDavid du Colombier alpha(char *s, char *t)
5253e12c5d1SDavid du Colombier {
5263e12c5d1SDavid du Colombier 	int n;
5273e12c5d1SDavid du Colombier 
5283e12c5d1SDavid du Colombier 	n = strlen(t);
5293e12c5d1SDavid du Colombier 	if(strncmp(s, t, n)==0 && (s[n]<'a' || 'z'<s[n]))
5303e12c5d1SDavid du Colombier 		return skipbl(s+n);
5313e12c5d1SDavid du Colombier 	return 0;
5323e12c5d1SDavid du Colombier 
5333e12c5d1SDavid du Colombier }
5343e12c5d1SDavid du Colombier 
5353e12c5d1SDavid du Colombier char*
text(char * s,char * t)5363e12c5d1SDavid du Colombier text(char *s, char *t)
5373e12c5d1SDavid du Colombier {
5383e12c5d1SDavid du Colombier 	int n;
5393e12c5d1SDavid du Colombier 
5403e12c5d1SDavid du Colombier 	n = strlen(t);
5413e12c5d1SDavid du Colombier 	if(strncmp(s, t, n)==0 && (s[n]==0 || s[n]==' ' || s[n]=='\t'))
5423e12c5d1SDavid du Colombier 		return skipbl(s+n);
5433e12c5d1SDavid du Colombier 	return 0;
5443e12c5d1SDavid du Colombier 
5453e12c5d1SDavid du Colombier }
5463e12c5d1SDavid du Colombier 
5473e12c5d1SDavid du Colombier int
cull(char * s,int keep,int dobbox)54859cc4ca5SDavid du Colombier cull(char *s, int keep, int dobbox)
5493e12c5d1SDavid du Colombier {
5503e12c5d1SDavid du Colombier 	int i, j, nobj, keepthis;
5513e12c5d1SDavid du Colombier 	Record *or;
5523e12c5d1SDavid du Colombier 	char *t;
553219b2ee8SDavid du Colombier 	int dogrtr, doless, dom, dosao, dongc, doabell;
5543e12c5d1SDavid du Colombier 	int mgrtr, mless;
5553e12c5d1SDavid du Colombier 	char obj[100];
5563e12c5d1SDavid du Colombier 
5573e12c5d1SDavid du Colombier 	memset(obj, 0, sizeof(obj));
5583e12c5d1SDavid du Colombier 	nobj = 0;
5593e12c5d1SDavid du Colombier 	dogrtr = 0;
5603e12c5d1SDavid du Colombier 	doless = 0;
5613e12c5d1SDavid du Colombier 	dom = 0;
5623e12c5d1SDavid du Colombier 	dongc = 0;
5633e12c5d1SDavid du Colombier 	dosao = 0;
564219b2ee8SDavid du Colombier 	doabell = 0;
5653e12c5d1SDavid du Colombier 	mgrtr = mless= 0;
56659cc4ca5SDavid du Colombier 	if(dobbox)
56759cc4ca5SDavid du Colombier 		goto Cull;
5683e12c5d1SDavid du Colombier 	for(;;){
5693e12c5d1SDavid du Colombier 		if(s[0] == '>'){
5703e12c5d1SDavid du Colombier 			dogrtr = 1;
5713e12c5d1SDavid du Colombier 			mgrtr = 10 * strtod(s+1, &t);
5723e12c5d1SDavid du Colombier 			if(mgrtr==0  && t==s+1){
5733e12c5d1SDavid du Colombier 				fprint(2, "bad magnitude\n");
5743e12c5d1SDavid du Colombier 				return 0;
5753e12c5d1SDavid du Colombier 			}
5763e12c5d1SDavid du Colombier 			s = skipbl(t);
5773e12c5d1SDavid du Colombier 			continue;
5783e12c5d1SDavid du Colombier 		}
5793e12c5d1SDavid du Colombier 		if(s[0] == '<'){
5803e12c5d1SDavid du Colombier 			doless = 1;
5813e12c5d1SDavid du Colombier 			mless = 10 * strtod(s+1, &t);
5823e12c5d1SDavid du Colombier 			if(mless==0  && t==s+1){
5833e12c5d1SDavid du Colombier 				fprint(2, "bad magnitude\n");
5843e12c5d1SDavid du Colombier 				return 0;
5853e12c5d1SDavid du Colombier 			}
5863e12c5d1SDavid du Colombier 			s = skipbl(t);
5873e12c5d1SDavid du Colombier 			continue;
5883e12c5d1SDavid du Colombier 		}
5893e12c5d1SDavid du Colombier 		if(t = text(s, "m")){
5903e12c5d1SDavid du Colombier  			dom = 1;
5913e12c5d1SDavid du Colombier 			s = t;
5923e12c5d1SDavid du Colombier 			continue;
5933e12c5d1SDavid du Colombier 		}
5943e12c5d1SDavid du Colombier 		if(t = text(s, "sao")){
5953e12c5d1SDavid du Colombier 			dosao = 1;
5963e12c5d1SDavid du Colombier 			s = t;
5973e12c5d1SDavid du Colombier 			continue;
5983e12c5d1SDavid du Colombier 		}
5993e12c5d1SDavid du Colombier 		if(t = text(s, "ngc")){
6003e12c5d1SDavid du Colombier 			dongc = 1;
6013e12c5d1SDavid du Colombier 			s = t;
6023e12c5d1SDavid du Colombier 			continue;
6033e12c5d1SDavid du Colombier 		}
604219b2ee8SDavid du Colombier 		if(t = text(s, "abell")){
605219b2ee8SDavid du Colombier 			doabell = 1;
606219b2ee8SDavid du Colombier 			s = t;
607219b2ee8SDavid du Colombier 			continue;
608219b2ee8SDavid du Colombier 		}
6093e12c5d1SDavid du Colombier 		for(i=0; names[i].name; i++)
6103e12c5d1SDavid du Colombier 			if(t = alpha(s, names[i].name)){
6113e12c5d1SDavid du Colombier 				if(nobj > 100){
6123e12c5d1SDavid du Colombier 					fprint(2, "too many object types\n");
6133e12c5d1SDavid du Colombier 					return 0;
6143e12c5d1SDavid du Colombier 				}
6153e12c5d1SDavid du Colombier 				obj[nobj++] = names[i].type;
6163e12c5d1SDavid du Colombier 				s = t;
6173e12c5d1SDavid du Colombier 				goto Continue;
6183e12c5d1SDavid du Colombier 			}
6193e12c5d1SDavid du Colombier 		break;
6203e12c5d1SDavid du Colombier 	    Continue:;
6213e12c5d1SDavid du Colombier 	}
6223e12c5d1SDavid du Colombier 	if(*s){
6233e12c5d1SDavid du Colombier 		fprint(2, "syntax error in object list\n");
6243e12c5d1SDavid du Colombier 		return 0;
6253e12c5d1SDavid du Colombier 	}
6263e12c5d1SDavid du Colombier 
62759cc4ca5SDavid du Colombier     Cull:
6283e12c5d1SDavid du Colombier 	flatten();
6293e12c5d1SDavid du Colombier 	copy();
6303e12c5d1SDavid du Colombier 	reset();
6313e12c5d1SDavid du Colombier 	if(dom)
6323e12c5d1SDavid du Colombier 		mopen();
6333e12c5d1SDavid du Colombier 	if(dosao)
6343e12c5d1SDavid du Colombier 		saoopen();
6353e12c5d1SDavid du Colombier 	if(dongc || nobj)
6363e12c5d1SDavid du Colombier 		ngcopen();
637219b2ee8SDavid du Colombier 	if(doabell)
638219b2ee8SDavid du Colombier 		abellopen();
6393e12c5d1SDavid du Colombier 	for(i=0,or=orec; i<norec; i++,or++){
6403e12c5d1SDavid du Colombier 		keepthis = !keep;
64159cc4ca5SDavid du Colombier 		if(dobbox && inbbox(or->ngc.ra, or->ngc.dec))
64259cc4ca5SDavid du Colombier 			keepthis = keep;
6433e12c5d1SDavid du Colombier 		if(doless && or->ngc.mag <= mless)
6443e12c5d1SDavid du Colombier 			keepthis = keep;
6453e12c5d1SDavid du Colombier 		if(dogrtr && or->ngc.mag >= mgrtr)
6463e12c5d1SDavid du Colombier 			keepthis = keep;
6473e12c5d1SDavid du Colombier 		if(dom && (or->type==NGC && ism(or->ngc.ngc)))
6483e12c5d1SDavid du Colombier 			keepthis = keep;
6493e12c5d1SDavid du Colombier 		if(dongc && or->type==NGC)
6503e12c5d1SDavid du Colombier 			keepthis = keep;
651219b2ee8SDavid du Colombier 		if(doabell && or->type==Abell)
652219b2ee8SDavid du Colombier 			keepthis = keep;
6533e12c5d1SDavid du Colombier 		if(dosao && or->type==SAO)
6543e12c5d1SDavid du Colombier 			keepthis = keep;
6553e12c5d1SDavid du Colombier 		for(j=0; j<nobj; j++)
6563e12c5d1SDavid du Colombier 			if(or->type==NGC && or->ngc.type==obj[j])
6573e12c5d1SDavid du Colombier 				keepthis = keep;
6583e12c5d1SDavid du Colombier 		if(keepthis){
6593e12c5d1SDavid du Colombier 			grow();
6603e12c5d1SDavid du Colombier 			memmove(cur, or, sizeof(Record));
6613e12c5d1SDavid du Colombier 		}
6623e12c5d1SDavid du Colombier 	}
6633e12c5d1SDavid du Colombier 	return 1;
6643e12c5d1SDavid du Colombier }
6653e12c5d1SDavid du Colombier 
6663e12c5d1SDavid du Colombier int
compar(void * va,void * vb)6673e12c5d1SDavid du Colombier compar(void *va, void *vb)
6683e12c5d1SDavid du Colombier {
6693e12c5d1SDavid du Colombier 	Record *a=va, *b=vb;
6703e12c5d1SDavid du Colombier 
6713e12c5d1SDavid du Colombier 	if(a->type == b->type)
6723e12c5d1SDavid du Colombier 		return a->index - b->index;
6733e12c5d1SDavid du Colombier 	return a->type - b->type;
6743e12c5d1SDavid du Colombier }
6753e12c5d1SDavid du Colombier 
6763e12c5d1SDavid du Colombier void
sort(void)6773e12c5d1SDavid du Colombier sort(void)
6783e12c5d1SDavid du Colombier {
6793e12c5d1SDavid du Colombier 	int i;
6803e12c5d1SDavid du Colombier 	Record *r, *s;
6813e12c5d1SDavid du Colombier 
6823e12c5d1SDavid du Colombier 	if(nrec == 0)
6833e12c5d1SDavid du Colombier 		return;
6843e12c5d1SDavid du Colombier 	qsort(rec, nrec, sizeof(Record), compar);
6853e12c5d1SDavid du Colombier 	r = rec+1;
6863e12c5d1SDavid du Colombier 	s = rec;
6873e12c5d1SDavid du Colombier 	for(i=1; i<nrec; i++,r++){
68859cc4ca5SDavid du Colombier 		/* may have multiple instances of a planet in the scene */
68959cc4ca5SDavid du Colombier 		if(r->type==s->type && r->index==s->index && r->type!=Planet)
6903e12c5d1SDavid du Colombier 			continue;
6913e12c5d1SDavid du Colombier 		memmove(++s, r, sizeof(Record));
6923e12c5d1SDavid du Colombier 	}
6933e12c5d1SDavid du Colombier 	nrec = (s+1)-rec;
6943e12c5d1SDavid du Colombier }
6953e12c5d1SDavid du Colombier 
6963e12c5d1SDavid du Colombier char	greekbuf[128];
6973e12c5d1SDavid du Colombier 
6983e12c5d1SDavid du Colombier char*
togreek(char * s)6993e12c5d1SDavid du Colombier togreek(char *s)
7003e12c5d1SDavid du Colombier {
7013e12c5d1SDavid du Colombier 	char *t;
7023e12c5d1SDavid du Colombier 	int i, n;
7033e12c5d1SDavid du Colombier 	Rune r;
7043e12c5d1SDavid du Colombier 
7053e12c5d1SDavid du Colombier 	t = greekbuf;
7063e12c5d1SDavid du Colombier 	while(*s){
7073e12c5d1SDavid du Colombier 		for(i=1; i<=24; i++){
7083e12c5d1SDavid du Colombier 			n = strlen(greek[i]);
7093e12c5d1SDavid du Colombier 			if(strncmp(s, greek[i], n)==0 && (s[n]==' ' || s[n]=='\t')){
7103e12c5d1SDavid du Colombier 				s += n;
7113e12c5d1SDavid du Colombier 				t += runetochar(t, &greeklet[i]);
7123e12c5d1SDavid du Colombier 				goto Cont;
7133e12c5d1SDavid du Colombier 			}
7143e12c5d1SDavid du Colombier 		}
7153e12c5d1SDavid du Colombier 		n = chartorune(&r, s);
7163e12c5d1SDavid du Colombier 		for(i=0; i<n; i++)
7173e12c5d1SDavid du Colombier 			*t++ = *s++;
7183e12c5d1SDavid du Colombier     Cont:;
7193e12c5d1SDavid du Colombier 	}
7203e12c5d1SDavid du Colombier 	*t = 0;
7213e12c5d1SDavid du Colombier 	return greekbuf;
7223e12c5d1SDavid du Colombier }
7233e12c5d1SDavid du Colombier 
7243e12c5d1SDavid du Colombier char*
fromgreek(char * s)7253e12c5d1SDavid du Colombier fromgreek(char *s)
7263e12c5d1SDavid du Colombier {
7273e12c5d1SDavid du Colombier 	char *t;
7283e12c5d1SDavid du Colombier 	int i, n;
7293e12c5d1SDavid du Colombier 	Rune r;
7303e12c5d1SDavid du Colombier 
7313e12c5d1SDavid du Colombier 	t = greekbuf;
7323e12c5d1SDavid du Colombier 	while(*s){
7333e12c5d1SDavid du Colombier 		n = chartorune(&r, s);
7343e12c5d1SDavid du Colombier 		for(i=1; i<=24; i++){
7353e12c5d1SDavid du Colombier 			if(r == greeklet[i]){
7363e12c5d1SDavid du Colombier 				strcpy(t, greek[i]);
7373e12c5d1SDavid du Colombier 				t += strlen(greek[i]);
7383e12c5d1SDavid du Colombier 				s += n;
7393e12c5d1SDavid du Colombier 				goto Cont;
7403e12c5d1SDavid du Colombier 			}
7413e12c5d1SDavid du Colombier 		}
7423e12c5d1SDavid du Colombier 		for(i=0; i<n; i++)
7433e12c5d1SDavid du Colombier 			*t++ = *s++;
7443e12c5d1SDavid du Colombier     Cont:;
7453e12c5d1SDavid du Colombier 	}
7463e12c5d1SDavid du Colombier 	*t = 0;
7473e12c5d1SDavid du Colombier 	return greekbuf;
7483e12c5d1SDavid du Colombier }
7493e12c5d1SDavid du Colombier 
75059cc4ca5SDavid du Colombier #ifdef OLD
75159cc4ca5SDavid du Colombier /*
75259cc4ca5SDavid du Colombier  * Old version
75359cc4ca5SDavid du Colombier  */
7543e12c5d1SDavid du Colombier int
coords(int deg)7553e12c5d1SDavid du Colombier coords(int deg)
7563e12c5d1SDavid du Colombier {
7573e12c5d1SDavid du Colombier 	int i;
7583e12c5d1SDavid du Colombier 	int x, y;
7593e12c5d1SDavid du Colombier 	Record *or;
7603e12c5d1SDavid du Colombier 	long dec, ra, ndec, nra;
7613e12c5d1SDavid du Colombier 	int rdeg;
7623e12c5d1SDavid du Colombier 
7633e12c5d1SDavid du Colombier 	flatten();
7643e12c5d1SDavid du Colombier 	copy();
7653e12c5d1SDavid du Colombier 	reset();
7663e12c5d1SDavid du Colombier 	deg *= 2;
7673e12c5d1SDavid du Colombier 	for(i=0,or=orec; i<norec; i++,or++){
76859cc4ca5SDavid du Colombier 		if(or->type == Planet)	/* must keep it here */
76959cc4ca5SDavid du Colombier 			loadplanet(or->index, or);
77059cc4ca5SDavid du Colombier 		dec = or->ngc.dec/MILLIARCSEC;
77159cc4ca5SDavid du Colombier 		ra = or->ngc.ra/MILLIARCSEC;
7723e12c5d1SDavid du Colombier 		rdeg = deg/cos((dec*PI)/180);
7733e12c5d1SDavid du Colombier 		for(y=-deg; y<=+deg; y++){
7743e12c5d1SDavid du Colombier 			ndec = dec*2+y;
7753e12c5d1SDavid du Colombier 			if(ndec/2>=90 || ndec/2<=-90)
7763e12c5d1SDavid du Colombier 				continue;
7773e12c5d1SDavid du Colombier 			/* fp errors hurt here, so we round 1' to the pole */
7783e12c5d1SDavid du Colombier 			if(ndec >= 0)
7793e12c5d1SDavid du Colombier 				ndec = ndec*500*60*60 + 60000;
7803e12c5d1SDavid du Colombier 			else
7813e12c5d1SDavid du Colombier 				ndec = ndec*500*60*60 - 60000;
7823e12c5d1SDavid du Colombier 			for(x=-rdeg; x<=+rdeg; x++){
7833e12c5d1SDavid du Colombier 				nra = ra*2+x;
7843e12c5d1SDavid du Colombier 				if(nra/2 < 0)
7853e12c5d1SDavid du Colombier 					nra += 360*2;
7863e12c5d1SDavid du Colombier 				if(nra/2 >= 360)
7873e12c5d1SDavid du Colombier 					nra -= 360*2;
7883e12c5d1SDavid du Colombier 				/* fp errors hurt here, so we round up 1' */
78959cc4ca5SDavid du Colombier 				nra = nra/2*MILLIARCSEC + 60000;
7903e12c5d1SDavid du Colombier 				loadpatch(patcha(angle(nra), angle(ndec)));
7913e12c5d1SDavid du Colombier 			}
7923e12c5d1SDavid du Colombier 		}
7933e12c5d1SDavid du Colombier 	}
7943e12c5d1SDavid du Colombier 	sort();
7953e12c5d1SDavid du Colombier 	return 1;
7963e12c5d1SDavid du Colombier }
79759cc4ca5SDavid du Colombier #endif
7983e12c5d1SDavid du Colombier 
79959cc4ca5SDavid du Colombier /*
80059cc4ca5SDavid du Colombier  * New version attempts to match the boundaries of the plot better.
80159cc4ca5SDavid du Colombier  */
8023e12c5d1SDavid du Colombier int
coords(int deg)80359cc4ca5SDavid du Colombier coords(int deg)
8043e12c5d1SDavid du Colombier {
8053e12c5d1SDavid du Colombier 	int i;
80659cc4ca5SDavid du Colombier 	int x, y, xx;
80759cc4ca5SDavid du Colombier 	Record *or;
80859cc4ca5SDavid du Colombier 	long min, circle;
80959cc4ca5SDavid du Colombier 	double factor;
8103e12c5d1SDavid du Colombier 
8113e12c5d1SDavid du Colombier 	flatten();
81259cc4ca5SDavid du Colombier 	circle = 360*MILLIARCSEC;
81359cc4ca5SDavid du Colombier 	deg *= MILLIARCSEC;
81459cc4ca5SDavid du Colombier 
81559cc4ca5SDavid du Colombier 	/* find center */
8163e12c5d1SDavid du Colombier 	folded = 0;
81759cc4ca5SDavid du Colombier 	bbox(0, 0, 0);
81859cc4ca5SDavid du Colombier 	/* now expand */
81959cc4ca5SDavid du Colombier 	factor = cos(angle((decmax+decmin)/2));
82059cc4ca5SDavid du Colombier 	if(factor < .2)
82159cc4ca5SDavid du Colombier 		factor = .2;
82259cc4ca5SDavid du Colombier 	factor = floor(1/factor);
82359cc4ca5SDavid du Colombier 	folded = 0;
82459cc4ca5SDavid du Colombier 	bbox(factor*deg, deg, 1);
82559cc4ca5SDavid du Colombier 	Bprint(&bout, "%s to ", hms(angle(ramin)));
82659cc4ca5SDavid du Colombier 	Bprint(&bout, "%s\n", hms(angle(ramax)));
82759cc4ca5SDavid du Colombier 	Bprint(&bout, "%s to ", dms(angle(decmin)));
82859cc4ca5SDavid du Colombier 	Bprint(&bout, "%s\n", dms(angle(decmax)));
82959cc4ca5SDavid du Colombier 	copy();
83059cc4ca5SDavid du Colombier 	reset();
83159cc4ca5SDavid du Colombier 	for(i=0,or=orec; i<norec; i++,or++)
83259cc4ca5SDavid du Colombier 		if(or->type == Planet)	/* must keep it here */
83359cc4ca5SDavid du Colombier 			loadplanet(or->index, or);
83459cc4ca5SDavid du Colombier 	min = ramin;
83559cc4ca5SDavid du Colombier 	if(ramin > ramax)
83659cc4ca5SDavid du Colombier 		min -= circle;
83759cc4ca5SDavid du Colombier 	for(x=min; x<=ramax; x+=250*60*60){
83859cc4ca5SDavid du Colombier 		xx = x;
83959cc4ca5SDavid du Colombier 		if(xx < 0)
84059cc4ca5SDavid du Colombier 			xx += circle;
84159cc4ca5SDavid du Colombier 		for(y=decmin; y<=decmax; y+=250*60*60)
84259cc4ca5SDavid du Colombier 			if(-circle/4 < y && y < circle/4)
84359cc4ca5SDavid du Colombier 				loadpatch(patcha(angle(xx), angle(y)));
8443e12c5d1SDavid du Colombier 	}
84559cc4ca5SDavid du Colombier 	sort();
84659cc4ca5SDavid du Colombier 	cull(nil, 1, 1);
84759cc4ca5SDavid du Colombier 	return 1;
8483e12c5d1SDavid du Colombier }
8493e12c5d1SDavid du Colombier 
8503e12c5d1SDavid du Colombier void
pplate(char * flags)851219b2ee8SDavid du Colombier pplate(char *flags)
852219b2ee8SDavid du Colombier {
853219b2ee8SDavid du Colombier 	int i;
854219b2ee8SDavid du Colombier 	long c;
855219b2ee8SDavid du Colombier 	int na, rah, ram, d1, d2;
856219b2ee8SDavid du Colombier 	double r0;
857219b2ee8SDavid du Colombier 	int ra, dec;
858219b2ee8SDavid du Colombier 	long ramin, ramax, decmin, decmax;	/* all in degrees */
859219b2ee8SDavid du Colombier 	Record *r;
860219b2ee8SDavid du Colombier 	int folded;
861219b2ee8SDavid du Colombier 	Angle racenter, deccenter, rasize, decsize, a[4];
862219b2ee8SDavid du Colombier 	Picture *pic;
863219b2ee8SDavid du Colombier 
864219b2ee8SDavid du Colombier 	rasize = -1.0;
865219b2ee8SDavid du Colombier 	decsize = -1.0;
866219b2ee8SDavid du Colombier 	na = 0;
867219b2ee8SDavid du Colombier 	for(;;){
868219b2ee8SDavid du Colombier 		while(*flags==' ')
869219b2ee8SDavid du Colombier 			flags++;
870219b2ee8SDavid du Colombier 		if(('0'<=*flags && *flags<='9') || *flags=='+' || *flags=='-'){
871219b2ee8SDavid du Colombier 			if(na >= 3)
872219b2ee8SDavid du Colombier 				goto err;
873219b2ee8SDavid du Colombier 			a[na++] = getra(flags);
874219b2ee8SDavid du Colombier 			while(*flags && *flags!=' ')
875219b2ee8SDavid du Colombier 				flags++;
876219b2ee8SDavid du Colombier 			continue;
877219b2ee8SDavid du Colombier 		}
878219b2ee8SDavid du Colombier 		if(*flags){
879219b2ee8SDavid du Colombier 	err:
880219b2ee8SDavid du Colombier 			Bprint(&bout, "syntax error in plate\n");
881219b2ee8SDavid du Colombier 			return;
882219b2ee8SDavid du Colombier 		}
883219b2ee8SDavid du Colombier 		break;
884219b2ee8SDavid du Colombier 	}
885219b2ee8SDavid du Colombier 	switch(na){
886219b2ee8SDavid du Colombier 	case 0:
887219b2ee8SDavid du Colombier 		break;
888219b2ee8SDavid du Colombier 	case 1:
889219b2ee8SDavid du Colombier 		rasize = a[0];
890219b2ee8SDavid du Colombier 		decsize = rasize;
891219b2ee8SDavid du Colombier 		break;
892219b2ee8SDavid du Colombier 	case 2:
893219b2ee8SDavid du Colombier 		rasize = a[0];
894219b2ee8SDavid du Colombier 		decsize = a[1];
895219b2ee8SDavid du Colombier 		break;
896219b2ee8SDavid du Colombier 	case 3:
897219b2ee8SDavid du Colombier 	case 4:
898219b2ee8SDavid du Colombier 		racenter = a[0];
899219b2ee8SDavid du Colombier 		deccenter = a[1];
900219b2ee8SDavid du Colombier 		rasize = a[2];
901219b2ee8SDavid du Colombier 		if(na == 4)
902219b2ee8SDavid du Colombier 			decsize = a[3];
903219b2ee8SDavid du Colombier 		else
904219b2ee8SDavid du Colombier 			decsize = rasize;
905219b2ee8SDavid du Colombier 		if(rasize<0.0 || decsize<0.0){
906219b2ee8SDavid du Colombier 			Bprint(&bout, "negative sizes\n");
907219b2ee8SDavid du Colombier 			return;
908219b2ee8SDavid du Colombier 		}
909219b2ee8SDavid du Colombier 		goto done;
910219b2ee8SDavid du Colombier 	}
911219b2ee8SDavid du Colombier 	folded = 0;
912219b2ee8SDavid du Colombier 	/* convert to milliarcsec */
913219b2ee8SDavid du Colombier 	c = 1000*60*60;
914219b2ee8SDavid du Colombier     Again:
915219b2ee8SDavid du Colombier 	if(nrec == 0){
916219b2ee8SDavid du Colombier 		Bprint(&bout, "empty\n");
917219b2ee8SDavid du Colombier 		return;
918219b2ee8SDavid du Colombier 	}
919219b2ee8SDavid du Colombier 	ramin = 0x7FFFFFFF;
920219b2ee8SDavid du Colombier 	ramax = -0x7FFFFFFF;
921219b2ee8SDavid du Colombier 	decmin = 0x7FFFFFFF;
922219b2ee8SDavid du Colombier 	decmax = -0x7FFFFFFF;
923219b2ee8SDavid du Colombier 	for(r=rec,i=0; i<nrec; i++,r++){
924219b2ee8SDavid du Colombier 		if(r->type == Patch){
925219b2ee8SDavid du Colombier 			radec(r->index, &rah, &ram, &dec);
926219b2ee8SDavid du Colombier 			ra = 15*rah+ram/4;
927219b2ee8SDavid du Colombier 			r0 = c/cos(RAD(dec));
928219b2ee8SDavid du Colombier 			ra *= c;
929219b2ee8SDavid du Colombier 			dec *= c;
930219b2ee8SDavid du Colombier 			if(dec == 0)
931219b2ee8SDavid du Colombier 				d1 = c, d2 = c;
932219b2ee8SDavid du Colombier 			else if(dec < 0)
933219b2ee8SDavid du Colombier 				d1 = c, d2 = 0;
934219b2ee8SDavid du Colombier 			else
935219b2ee8SDavid du Colombier 				d1 = 0, d2 = c;
936219b2ee8SDavid du Colombier 		}else if(r->type==SAO || r->type==NGC || r->type==Abell){
937219b2ee8SDavid du Colombier 			ra = r->ngc.ra;
938219b2ee8SDavid du Colombier 			dec = r->ngc.dec;
939219b2ee8SDavid du Colombier 			d1 = 0, d2 = 0, r0 = 0;
940219b2ee8SDavid du Colombier 		}else if(r->type==NGCN){
941219b2ee8SDavid du Colombier 			loadngc(r->index);
942219b2ee8SDavid du Colombier 			continue;
943219b2ee8SDavid du Colombier 		}else if(r->type==NamedSAO){
944219b2ee8SDavid du Colombier 			loadsao(r->index);
945219b2ee8SDavid du Colombier 			continue;
946219b2ee8SDavid du Colombier 		}else if(r->type==NamedNGC){
947219b2ee8SDavid du Colombier 			loadngc(r->index);
948219b2ee8SDavid du Colombier 			continue;
949219b2ee8SDavid du Colombier 		}else if(r->type==NamedAbell){
950219b2ee8SDavid du Colombier 			loadabell(r->index);
951219b2ee8SDavid du Colombier 			continue;
952219b2ee8SDavid du Colombier 		}else
953219b2ee8SDavid du Colombier 			continue;
954219b2ee8SDavid du Colombier 		if(dec+d2 > decmax)
955219b2ee8SDavid du Colombier 			decmax = dec+d2;
956219b2ee8SDavid du Colombier 		if(dec-d1 < decmin)
957219b2ee8SDavid du Colombier 			decmin = dec-d1;
958219b2ee8SDavid du Colombier 		if(folded){
959219b2ee8SDavid du Colombier 			ra -= 180*c;
960219b2ee8SDavid du Colombier 			if(ra < 0)
961219b2ee8SDavid du Colombier 				ra += 360*c;
962219b2ee8SDavid du Colombier 		}
963219b2ee8SDavid du Colombier 		if(ra+r0 > ramax)
964219b2ee8SDavid du Colombier 			ramax = ra+r0;
965219b2ee8SDavid du Colombier 		if(ra < ramin)
966219b2ee8SDavid du Colombier 			ramin = ra;
967219b2ee8SDavid du Colombier 	}
968219b2ee8SDavid du Colombier 	if(!folded && ramax-ramin>270*c){
969219b2ee8SDavid du Colombier 		folded = 1;
970219b2ee8SDavid du Colombier 		goto Again;
971219b2ee8SDavid du Colombier 	}
972219b2ee8SDavid du Colombier 	racenter = angle(ramin+(ramax-ramin)/2);
973219b2ee8SDavid du Colombier 	deccenter = angle(decmin+(decmax-decmin)/2);
974219b2ee8SDavid du Colombier 	if(rasize<0 || decsize<0){
975219b2ee8SDavid du Colombier 		rasize = angle(ramax-ramin)*cos(deccenter);
976219b2ee8SDavid du Colombier 		decsize = angle(decmax-decmin);
977219b2ee8SDavid du Colombier 	}
978219b2ee8SDavid du Colombier     done:
979219b2ee8SDavid du Colombier 	if(DEG(rasize)>1.1 || DEG(decsize)>1.1){
980219b2ee8SDavid du Colombier 		Bprint(&bout, "plate too big: %s", ms(rasize));
981219b2ee8SDavid du Colombier 		Bprint(&bout, " x %s\n", ms(decsize));
982219b2ee8SDavid du Colombier 		Bprint(&bout, "trimming to 30'x30'\n");
983219b2ee8SDavid du Colombier 		rasize = RAD(0.5);
984219b2ee8SDavid du Colombier 		decsize = RAD(0.5);
985219b2ee8SDavid du Colombier 	}
986219b2ee8SDavid du Colombier 	Bprint(&bout, "%s %s ", hms(racenter), dms(deccenter));
987219b2ee8SDavid du Colombier 	Bprint(&bout, "%s", ms(rasize));
988219b2ee8SDavid du Colombier 	Bprint(&bout, " x %s\n", ms(decsize));
989219b2ee8SDavid du Colombier 	Bflush(&bout);
990219b2ee8SDavid du Colombier 	flatten();
991219b2ee8SDavid du Colombier 	pic = image(racenter, deccenter, rasize, decsize);
992219b2ee8SDavid du Colombier 	if(pic == 0)
993219b2ee8SDavid du Colombier 		return;
994219b2ee8SDavid du Colombier 	Bprint(&bout, "plate %s locn %d %d %d %d\n", pic->name, pic->minx, pic->miny, pic->maxx, pic->maxy);
995219b2ee8SDavid du Colombier 	Bflush(&bout);
9967dd7cddfSDavid du Colombier 	displaypic(pic);
997219b2ee8SDavid du Colombier }
998219b2ee8SDavid du Colombier 
999219b2ee8SDavid du Colombier void
lookup(char * s,int doreset)10003e12c5d1SDavid du Colombier lookup(char *s, int doreset)
10013e12c5d1SDavid du Colombier {
1002219b2ee8SDavid du Colombier 	int i, j, k;
10033e12c5d1SDavid du Colombier 	int rah, ram, deg;
10043e12c5d1SDavid du Colombier 	char *starts, *inputline=s, *t, *u;
10053e12c5d1SDavid du Colombier 	Record *r;
10063e12c5d1SDavid du Colombier 	long n;
10073e12c5d1SDavid du Colombier 	double x;
1008219b2ee8SDavid du Colombier 	Angle ra;
10093e12c5d1SDavid du Colombier 
10103e12c5d1SDavid du Colombier 	lowercase(s);
10113e12c5d1SDavid du Colombier 	s = skipbl(s);
10123e12c5d1SDavid du Colombier 
10133e12c5d1SDavid du Colombier 	if(*s == 0)
10143e12c5d1SDavid du Colombier 		goto Print;
10153e12c5d1SDavid du Colombier 
10163e12c5d1SDavid du Colombier 	if(t = alpha(s, "flat")){
10173e12c5d1SDavid du Colombier 		if(*t){
10183e12c5d1SDavid du Colombier 			fprint(2, "flat takes no arguments\n");
10193e12c5d1SDavid du Colombier 			return;
10203e12c5d1SDavid du Colombier 		}
10213e12c5d1SDavid du Colombier 		if(nrec == 0){
10223e12c5d1SDavid du Colombier 			fprint(2, "no records\n");
10233e12c5d1SDavid du Colombier 			return;
10243e12c5d1SDavid du Colombier 		}
10253e12c5d1SDavid du Colombier 		flatten();
10263e12c5d1SDavid du Colombier 		goto Print;
10273e12c5d1SDavid du Colombier 	}
10283e12c5d1SDavid du Colombier 
10293e12c5d1SDavid du Colombier 	if(t = alpha(s, "print")){
10303e12c5d1SDavid du Colombier 		if(*t){
10313e12c5d1SDavid du Colombier 			fprint(2, "print takes no arguments\n");
10323e12c5d1SDavid du Colombier 			return;
10333e12c5d1SDavid du Colombier 		}
10343e12c5d1SDavid du Colombier 		for(i=0,r=rec; i<nrec; i++,r++)
10353e12c5d1SDavid du Colombier 			prrec(r);
10363e12c5d1SDavid du Colombier 		return;
10373e12c5d1SDavid du Colombier 	}
10383e12c5d1SDavid du Colombier 
10393e12c5d1SDavid du Colombier 	if(t = alpha(s, "add")){
10403e12c5d1SDavid du Colombier 		lookup(t, 0);
10413e12c5d1SDavid du Colombier 		return;
10423e12c5d1SDavid du Colombier 	}
10433e12c5d1SDavid du Colombier 
10443e12c5d1SDavid du Colombier 	if(t = alpha(s, "sao")){
10453e12c5d1SDavid du Colombier 		n = strtoul(t, &u, 10);
10463e12c5d1SDavid du Colombier 		if(n<=0 || n>NSAO)
10473e12c5d1SDavid du Colombier 			goto NotFound;
10483e12c5d1SDavid du Colombier 		t = skipbl(u);
10493e12c5d1SDavid du Colombier 		if(*t){
10503e12c5d1SDavid du Colombier 			fprint(2, "syntax error in sao\n");
10513e12c5d1SDavid du Colombier 			return;
10523e12c5d1SDavid du Colombier 		}
10533e12c5d1SDavid du Colombier 		if(doreset)
10543e12c5d1SDavid du Colombier 			reset();
10553e12c5d1SDavid du Colombier 		if(!loadsao(n))
10563e12c5d1SDavid du Colombier 			goto NotFound;
10573e12c5d1SDavid du Colombier 		goto Print;
10583e12c5d1SDavid du Colombier 	}
10593e12c5d1SDavid du Colombier 
10603e12c5d1SDavid du Colombier 	if(t = alpha(s, "ngc")){
10613e12c5d1SDavid du Colombier 		n = strtoul(t, &u, 10);
10623e12c5d1SDavid du Colombier 		if(n<=0 || n>NNGC)
10633e12c5d1SDavid du Colombier 			goto NotFound;
10643e12c5d1SDavid du Colombier 		t = skipbl(u);
10653e12c5d1SDavid du Colombier 		if(*t){
10663e12c5d1SDavid du Colombier 			fprint(2, "syntax error in ngc\n");
10673e12c5d1SDavid du Colombier 			return;
10683e12c5d1SDavid du Colombier 		}
10693e12c5d1SDavid du Colombier 		if(doreset)
10703e12c5d1SDavid du Colombier 			reset();
1071219b2ee8SDavid du Colombier 		if(!loadngc(n))
1072219b2ee8SDavid du Colombier 			goto NotFound;
1073219b2ee8SDavid du Colombier 		goto Print;
1074219b2ee8SDavid du Colombier 	}
1075219b2ee8SDavid du Colombier 
1076219b2ee8SDavid du Colombier 	if(t = alpha(s, "ic")){
1077219b2ee8SDavid du Colombier 		n = strtoul(t, &u, 10);
1078219b2ee8SDavid du Colombier 		if(n<=0 || n>NIC)
1079219b2ee8SDavid du Colombier 			goto NotFound;
1080219b2ee8SDavid du Colombier 		t = skipbl(u);
1081219b2ee8SDavid du Colombier 		if(*t){
1082219b2ee8SDavid du Colombier 			fprint(2, "syntax error in ic\n");
1083219b2ee8SDavid du Colombier 			return;
1084219b2ee8SDavid du Colombier 		}
1085219b2ee8SDavid du Colombier 		if(doreset)
1086219b2ee8SDavid du Colombier 			reset();
1087219b2ee8SDavid du Colombier 		if(!loadngc(n+NNGC))
1088219b2ee8SDavid du Colombier 			goto NotFound;
1089219b2ee8SDavid du Colombier 		goto Print;
1090219b2ee8SDavid du Colombier 	}
1091219b2ee8SDavid du Colombier 
1092219b2ee8SDavid du Colombier 	if(t = alpha(s, "abell")){
1093219b2ee8SDavid du Colombier 		n = strtoul(t, &u, 10);
1094219b2ee8SDavid du Colombier 		if(n<=0 || n>NAbell)
1095219b2ee8SDavid du Colombier 			goto NotFound;
1096219b2ee8SDavid du Colombier 		if(doreset)
1097219b2ee8SDavid du Colombier 			reset();
1098219b2ee8SDavid du Colombier 		if(!loadabell(n))
10993e12c5d1SDavid du Colombier 			goto NotFound;
11003e12c5d1SDavid du Colombier 		goto Print;
11013e12c5d1SDavid du Colombier 	}
11023e12c5d1SDavid du Colombier 
11033e12c5d1SDavid du Colombier 	if(t = alpha(s, "m")){
11043e12c5d1SDavid du Colombier 		n = strtoul(t, &u, 10);
11053e12c5d1SDavid du Colombier 		if(n<=0 || n>NM)
11063e12c5d1SDavid du Colombier 			goto NotFound;
11073e12c5d1SDavid du Colombier 		mopen();
11083e12c5d1SDavid du Colombier 		for(j=n-1; mindex[j].m<n; j++)
11093e12c5d1SDavid du Colombier 			;
11103e12c5d1SDavid du Colombier 		if(doreset)
11113e12c5d1SDavid du Colombier 			reset();
11123e12c5d1SDavid du Colombier 		while(mindex[j].m == n){
11133e12c5d1SDavid du Colombier 			if(mindex[j].ngc){
11143e12c5d1SDavid du Colombier 				grow();
11153e12c5d1SDavid du Colombier 				cur->type = NGCN;
11163e12c5d1SDavid du Colombier 				cur->index = mindex[j].ngc;
11173e12c5d1SDavid du Colombier 			}
11183e12c5d1SDavid du Colombier 			j++;
11193e12c5d1SDavid du Colombier 		}
11203e12c5d1SDavid du Colombier 		goto Print;
11213e12c5d1SDavid du Colombier 	}
11223e12c5d1SDavid du Colombier 
11233e12c5d1SDavid du Colombier 	for(i=1; i<=Ncon; i++)
11243e12c5d1SDavid du Colombier 		if(t = alpha(s, constel[i])){
11253e12c5d1SDavid du Colombier 			if(*t){
11263e12c5d1SDavid du Colombier 				fprint(2, "syntax error in constellation\n");
11273e12c5d1SDavid du Colombier 				return;
11283e12c5d1SDavid du Colombier 			}
11293e12c5d1SDavid du Colombier 			constelopen();
11303e12c5d1SDavid du Colombier 			seek(condb, 4L*conindex[i-1], 0);
11313e12c5d1SDavid du Colombier 			j = conindex[i]-conindex[i-1];
11323e12c5d1SDavid du Colombier 			Eread(condb, "con", con, 4*j);
11333e12c5d1SDavid du Colombier 			if(doreset)
11343e12c5d1SDavid du Colombier 				reset();
11353e12c5d1SDavid du Colombier 			for(k=0; k<j; k++){
11363e12c5d1SDavid du Colombier 				grow();
11373e12c5d1SDavid du Colombier 				cur->type = PatchC;
11383e12c5d1SDavid du Colombier 				cur->index = Long(&con[k]);
11393e12c5d1SDavid du Colombier 			}
11403e12c5d1SDavid du Colombier 			goto Print;
11413e12c5d1SDavid du Colombier 		}
11423e12c5d1SDavid du Colombier 
11433e12c5d1SDavid du Colombier 	if(t = alpha(s, "expand")){
11443e12c5d1SDavid du Colombier 		n = 0;
11453e12c5d1SDavid du Colombier 		if(*t){
11463e12c5d1SDavid du Colombier 			if(*t<'0' && '9'<*t){
11473e12c5d1SDavid du Colombier 		Expanderr:
11483e12c5d1SDavid du Colombier 				fprint(2, "syntax error in expand\n");
11493e12c5d1SDavid du Colombier 				return;
11503e12c5d1SDavid du Colombier 			}
11513e12c5d1SDavid du Colombier 			n = strtoul(t, &u, 10);
11523e12c5d1SDavid du Colombier 			t = skipbl(u);
11533e12c5d1SDavid du Colombier 			if(*t)
11543e12c5d1SDavid du Colombier 				goto Expanderr;
11553e12c5d1SDavid du Colombier 		}
11563e12c5d1SDavid du Colombier 		coords(n);
11573e12c5d1SDavid du Colombier 		goto Print;
11583e12c5d1SDavid du Colombier 	}
11593e12c5d1SDavid du Colombier 
11603e12c5d1SDavid du Colombier 	if(t = alpha(s, "plot")){
11613e12c5d1SDavid du Colombier 		if(nrec == 0){
11623e12c5d1SDavid du Colombier 			Bprint(&bout, "empty\n");
11633e12c5d1SDavid du Colombier 			return;
11643e12c5d1SDavid du Colombier 		}
11653e12c5d1SDavid du Colombier 		plot(t);
11663e12c5d1SDavid du Colombier 		return;
11673e12c5d1SDavid du Colombier 	}
11683e12c5d1SDavid du Colombier 
116959cc4ca5SDavid du Colombier 	if(t = alpha(s, "astro")){
117059cc4ca5SDavid du Colombier 		astro(t, 0);
117159cc4ca5SDavid du Colombier 		return;
117259cc4ca5SDavid du Colombier 	}
117359cc4ca5SDavid du Colombier 
1174219b2ee8SDavid du Colombier 	if(t = alpha(s, "plate")){
1175219b2ee8SDavid du Colombier 		pplate(t);
1176219b2ee8SDavid du Colombier 		return;
1177219b2ee8SDavid du Colombier 	}
1178219b2ee8SDavid du Colombier 
1179219b2ee8SDavid du Colombier 	if(t = alpha(s, "gamma")){
1180219b2ee8SDavid du Colombier 		while(*t==' ')
1181219b2ee8SDavid du Colombier 			t++;
1182219b2ee8SDavid du Colombier 		u = t;
1183219b2ee8SDavid du Colombier 		x = strtod(t, &u);
1184219b2ee8SDavid du Colombier 		if(u > t)
1185219b2ee8SDavid du Colombier 			gam.gamma = x;
118659cc4ca5SDavid du Colombier 		Bprint(&bout, "%.2f\n", gam.gamma);
1187219b2ee8SDavid du Colombier 		return;
1188219b2ee8SDavid du Colombier 	}
1189219b2ee8SDavid du Colombier 
11903e12c5d1SDavid du Colombier 	if(t = alpha(s, "keep")){
119159cc4ca5SDavid du Colombier 		if(!cull(t, 1, 0))
11923e12c5d1SDavid du Colombier 			return;
11933e12c5d1SDavid du Colombier 		goto Print;
11943e12c5d1SDavid du Colombier 	}
11953e12c5d1SDavid du Colombier 
11963e12c5d1SDavid du Colombier 	if(t = alpha(s, "drop")){
119759cc4ca5SDavid du Colombier 		if(!cull(t, 0, 0))
11983e12c5d1SDavid du Colombier 			return;
11993e12c5d1SDavid du Colombier 		goto Print;
12003e12c5d1SDavid du Colombier 	}
12013e12c5d1SDavid du Colombier 
120259cc4ca5SDavid du Colombier 	for(i=0; planet[i].name[0]; i++){
120359cc4ca5SDavid du Colombier 		if(t = alpha(s, planet[i].name)){
120459cc4ca5SDavid du Colombier 			if(doreset)
120559cc4ca5SDavid du Colombier 				reset();
120659cc4ca5SDavid du Colombier 			loadplanet(i, nil);
120759cc4ca5SDavid du Colombier 			goto Print;
120859cc4ca5SDavid du Colombier 		}
120959cc4ca5SDavid du Colombier 	}
121059cc4ca5SDavid du Colombier 
12113e12c5d1SDavid du Colombier 	for(i=0; names[i].name; i++){
12123e12c5d1SDavid du Colombier 		if(t = alpha(s, names[i].name)){
12133e12c5d1SDavid du Colombier 			if(*t){
12143e12c5d1SDavid du Colombier 				fprint(2, "syntax error in type\n");
12153e12c5d1SDavid du Colombier 				return;
12163e12c5d1SDavid du Colombier 			}
12173e12c5d1SDavid du Colombier 			if(doreset)
12183e12c5d1SDavid du Colombier 				reset();
12193e12c5d1SDavid du Colombier 			loadtype(names[i].type);
12203e12c5d1SDavid du Colombier 			goto Print;
12213e12c5d1SDavid du Colombier 		}
12223e12c5d1SDavid du Colombier 	}
12233e12c5d1SDavid du Colombier 
12243e12c5d1SDavid du Colombier 	switch(s[0]){
12253e12c5d1SDavid du Colombier 	case '"':
12263e12c5d1SDavid du Colombier 		starts = ++s;
12273e12c5d1SDavid du Colombier 		while(*s != '"')
12283e12c5d1SDavid du Colombier 			if(*s++ == 0){
12293e12c5d1SDavid du Colombier 				fprint(2, "bad star name\n");
12303e12c5d1SDavid du Colombier 				return;
12313e12c5d1SDavid du Colombier 			}
12323e12c5d1SDavid du Colombier 		*s = 0;
12333e12c5d1SDavid du Colombier 		if(doreset)
12343e12c5d1SDavid du Colombier 			reset();
1235219b2ee8SDavid du Colombier 		j = nrec;
12363e12c5d1SDavid du Colombier 		saoopen();
12373e12c5d1SDavid du Colombier 		starts = fromgreek(starts);
12383e12c5d1SDavid du Colombier 		for(i=0; i<NName; i++)
12393e12c5d1SDavid du Colombier 			if(equal(starts, name[i].name)){
12403e12c5d1SDavid du Colombier 				grow();
1241219b2ee8SDavid du Colombier 				if(name[i].sao){
1242219b2ee8SDavid du Colombier 					rec[j].type = NamedSAO;
12433e12c5d1SDavid du Colombier 					rec[j].index = name[i].sao;
1244219b2ee8SDavid du Colombier 				}
1245219b2ee8SDavid du Colombier 				if(name[i].ngc){
1246219b2ee8SDavid du Colombier 					rec[j].type = NamedNGC;
1247219b2ee8SDavid du Colombier 					rec[j].index = name[i].ngc;
1248219b2ee8SDavid du Colombier 				}
1249219b2ee8SDavid du Colombier 				if(name[i].abell){
1250219b2ee8SDavid du Colombier 					rec[j].type = NamedAbell;
1251219b2ee8SDavid du Colombier 					rec[j].index = name[i].abell;
1252219b2ee8SDavid du Colombier 				}
1253219b2ee8SDavid du Colombier 				strcpy(rec[j].named.name, name[i].name);
12543e12c5d1SDavid du Colombier 				j++;
12553e12c5d1SDavid du Colombier 			}
12563e12c5d1SDavid du Colombier 		if(parsename(starts))
12573e12c5d1SDavid du Colombier 			for(i=0; i<NBayer; i++)
12583e12c5d1SDavid du Colombier 				if(bayer[i].name[0]==parsed[0] &&
12593e12c5d1SDavid du Colombier 				  (bayer[i].name[1]==parsed[1] || parsed[1]==0) &&
12603e12c5d1SDavid du Colombier 				   bayer[i].name[2]==parsed[2]){
12613e12c5d1SDavid du Colombier 					grow();
1262219b2ee8SDavid du Colombier 					rec[j].type = NamedSAO;
12633e12c5d1SDavid du Colombier 					rec[j].index = bayer[i].sao;
1264219b2ee8SDavid du Colombier 					strncpy(rec[j].named.name, starts, sizeof(rec[j].named.name));
12653e12c5d1SDavid du Colombier 					j++;
12663e12c5d1SDavid du Colombier 				}
1267219b2ee8SDavid du Colombier 		if(j == 0){
1268219b2ee8SDavid du Colombier 			*s = '"';
12693e12c5d1SDavid du Colombier 			goto NotFound;
1270219b2ee8SDavid du Colombier 		}
12713e12c5d1SDavid du Colombier 		break;
12723e12c5d1SDavid du Colombier 
12733e12c5d1SDavid du Colombier 	case '0': case '1': case '2': case '3': case '4':
12743e12c5d1SDavid du Colombier 	case '5': case '6': case '7': case '8': case '9':
1275219b2ee8SDavid du Colombier 		strtoul(s, &t, 10);
1276219b2ee8SDavid du Colombier 		if(*t != 'h'){
12773e12c5d1SDavid du Colombier 	BadCoords:
12783e12c5d1SDavid du Colombier 			fprint(2, "bad coordinates %s\n", inputline);
12793e12c5d1SDavid du Colombier 			break;
12803e12c5d1SDavid du Colombier 		}
1281219b2ee8SDavid du Colombier 		ra = DEG(getra(s));
1282219b2ee8SDavid du Colombier 		while(*s && *s!=' ' && *s!='\t')
1283219b2ee8SDavid du Colombier 			s++;
1284219b2ee8SDavid du Colombier 		rah = ra/15;
1285219b2ee8SDavid du Colombier 		ra = ra-rah*15;
1286219b2ee8SDavid du Colombier 		ram = ra*4;
1287219b2ee8SDavid du Colombier 		deg = strtol(s, &t, 10);
1288219b2ee8SDavid du Colombier 		if(t == s)
12893e12c5d1SDavid du Colombier 			goto BadCoords;
1290219b2ee8SDavid du Colombier 		/* degree sign etc. is optional */
1291*22a127bbSDavid du Colombier 		if((uchar)*t == L'°')
1292219b2ee8SDavid du Colombier 			deg = DEG(getra(s));
12933e12c5d1SDavid du Colombier 		if(doreset)
12943e12c5d1SDavid du Colombier 			reset();
1295219b2ee8SDavid du Colombier 		if(abs(deg)>=90 || rah>=24)
12963e12c5d1SDavid du Colombier 			goto BadCoords;
12973e12c5d1SDavid du Colombier 		if(!loadpatch(patch(rah, ram, deg)))
12983e12c5d1SDavid du Colombier 			goto NotFound;
12993e12c5d1SDavid du Colombier 		break;
13003e12c5d1SDavid du Colombier 
13013e12c5d1SDavid du Colombier 	default:
13023e12c5d1SDavid du Colombier 		fprint(2, "unknown command %s\n", inputline);
13033e12c5d1SDavid du Colombier 		return;
13043e12c5d1SDavid du Colombier 	}
13053e12c5d1SDavid du Colombier 
13063e12c5d1SDavid du Colombier     Print:
13073e12c5d1SDavid du Colombier 	if(nrec == 0)
13083e12c5d1SDavid du Colombier 		Bprint(&bout, "empty\n");
13093e12c5d1SDavid du Colombier 	else if(nrec <= 2)
13103e12c5d1SDavid du Colombier 		for(i=0; i<nrec; i++)
13113e12c5d1SDavid du Colombier 			prrec(rec+i);
13123e12c5d1SDavid du Colombier 	else
13137dd7cddfSDavid du Colombier 		Bprint(&bout, "%ld items\n", nrec);
13143e12c5d1SDavid du Colombier 	return;
13153e12c5d1SDavid du Colombier 
13163e12c5d1SDavid du Colombier     NotFound:
13173e12c5d1SDavid du Colombier 	fprint(2, "%s not found\n", inputline);
13183e12c5d1SDavid du Colombier 	return;
13193e12c5d1SDavid du Colombier }
13203e12c5d1SDavid du Colombier 
1321219b2ee8SDavid du Colombier char *ngctypes[] =
13223e12c5d1SDavid du Colombier {
1323219b2ee8SDavid du Colombier [Galaxy] 		"Gx",
1324219b2ee8SDavid du Colombier [PlanetaryN]	"Pl",
1325219b2ee8SDavid du Colombier [OpenCl]		"OC",
1326219b2ee8SDavid du Colombier [GlobularCl]	"Gb",
1327219b2ee8SDavid du Colombier [DiffuseN]		"Nb",
1328219b2ee8SDavid du Colombier [NebularCl]	"C+N",
1329219b2ee8SDavid du Colombier [Asterism]		"Ast",
1330219b2ee8SDavid du Colombier [Knot]		"Kt",
1331219b2ee8SDavid du Colombier [Triple]		"***",
1332219b2ee8SDavid du Colombier [Double]		"D*",
1333219b2ee8SDavid du Colombier [Single]		"*",
1334219b2ee8SDavid du Colombier [Uncertain]	"?",
1335219b2ee8SDavid du Colombier [Nonexistent]	"-",
1336219b2ee8SDavid du Colombier [Unknown]	" ",
1337219b2ee8SDavid du Colombier [PlateDefect]	"PD",
13383e12c5d1SDavid du Colombier };
13393e12c5d1SDavid du Colombier 
13403e12c5d1SDavid du Colombier char*
ngcstring(int d)13413e12c5d1SDavid du Colombier ngcstring(int d)
13423e12c5d1SDavid du Colombier {
1343219b2ee8SDavid du Colombier 	if(d<Galaxy || d>PlateDefect)
1344219b2ee8SDavid du Colombier 		return "can't happen";
1345219b2ee8SDavid du Colombier 	return ngctypes[d];
13463e12c5d1SDavid du Colombier }
13473e12c5d1SDavid du Colombier 
1348219b2ee8SDavid du Colombier short	descindex[NINDEX];
13493e12c5d1SDavid du Colombier 
13503e12c5d1SDavid du Colombier void
printnames(Record * r)13513e12c5d1SDavid du Colombier printnames(Record *r)
13523e12c5d1SDavid du Colombier {
1353219b2ee8SDavid du Colombier 	int i, ok, done;
13543e12c5d1SDavid du Colombier 
1355219b2ee8SDavid du Colombier 	done = 0;
1356219b2ee8SDavid du Colombier 	for(i=0; i<NName; i++){	/* stupid linear search! */
1357219b2ee8SDavid du Colombier 		ok = 0;
1358219b2ee8SDavid du Colombier 		if(r->type==SAO && r->index==name[i].sao)
1359219b2ee8SDavid du Colombier 			ok = 1;
1360219b2ee8SDavid du Colombier 		if(r->type==NGC && r->ngc.ngc==name[i].ngc)
1361219b2ee8SDavid du Colombier 			ok = 1;
1362219b2ee8SDavid du Colombier 		if(r->type==Abell && r->abell.abell==name[i].abell)
1363219b2ee8SDavid du Colombier 			ok = 1;
1364219b2ee8SDavid du Colombier 		if(ok){
1365219b2ee8SDavid du Colombier 			if(done++ == 0)
1366219b2ee8SDavid du Colombier 				Bprint(&bout, "\t");
1367219b2ee8SDavid du Colombier 			Bprint(&bout, " \"%s\"", togreek(name[i].name));
13683e12c5d1SDavid du Colombier 		}
13693e12c5d1SDavid du Colombier 	}
1370219b2ee8SDavid du Colombier 	if(done)
1371219b2ee8SDavid du Colombier 		Bprint(&bout, "\n");
1372219b2ee8SDavid du Colombier }
13733e12c5d1SDavid du Colombier 
13743e12c5d1SDavid du Colombier int
equal(char * s1,char * s2)13753e12c5d1SDavid du Colombier equal(char *s1, char *s2)
13763e12c5d1SDavid du Colombier {
13773e12c5d1SDavid du Colombier 	int c;
13783e12c5d1SDavid du Colombier 
13793e12c5d1SDavid du Colombier 	while(*s1){
13803e12c5d1SDavid du Colombier 		if(*s1==' '){
13813e12c5d1SDavid du Colombier 			while(*s1==' ')
13823e12c5d1SDavid du Colombier 				s1++;
13833e12c5d1SDavid du Colombier 			continue;
13843e12c5d1SDavid du Colombier 		}
13853e12c5d1SDavid du Colombier 		while(*s2==' ')
13863e12c5d1SDavid du Colombier 			s2++;
13873e12c5d1SDavid du Colombier 		c=*s2;
13883e12c5d1SDavid du Colombier 		if('A'<=*s2 && *s2<='Z')
13893e12c5d1SDavid du Colombier 			c^=' ';
13903e12c5d1SDavid du Colombier 		if(*s1!=c)
13913e12c5d1SDavid du Colombier 			return 0;
13923e12c5d1SDavid du Colombier 		s1++, s2++;
13933e12c5d1SDavid du Colombier 	}
13943e12c5d1SDavid du Colombier 	return 1;
13953e12c5d1SDavid du Colombier }
13963e12c5d1SDavid du Colombier 
13973e12c5d1SDavid du Colombier int
parsename(char * s)13983e12c5d1SDavid du Colombier parsename(char *s)
13993e12c5d1SDavid du Colombier {
14003e12c5d1SDavid du Colombier 	char *blank;
14013e12c5d1SDavid du Colombier 	int i;
14023e12c5d1SDavid du Colombier 
14033e12c5d1SDavid du Colombier 	blank = strchr(s, ' ');
14043e12c5d1SDavid du Colombier 	if(blank==0 || strchr(blank+1, ' ') || strlen(blank+1)!=3)
14053e12c5d1SDavid du Colombier 		return 0;
14063e12c5d1SDavid du Colombier 	blank++;
14073e12c5d1SDavid du Colombier 	parsed[0] = parsed[1] = parsed[2] = 0;
14083e12c5d1SDavid du Colombier 	if('0'<=s[0] && s[0]<='9'){
14093e12c5d1SDavid du Colombier 		i = atoi(s);
14103e12c5d1SDavid du Colombier 		parsed[0] = i;
14113e12c5d1SDavid du Colombier 		if(i > 100)
14123e12c5d1SDavid du Colombier 			return 0;
14133e12c5d1SDavid du Colombier 	}else{
14143e12c5d1SDavid du Colombier 		for(i=1; i<=24; i++)
14153e12c5d1SDavid du Colombier 			if(strncmp(greek[i], s, strlen(greek[i]))==0){
14163e12c5d1SDavid du Colombier 				parsed[0]=100+i;
14173e12c5d1SDavid du Colombier 				goto out;
14183e12c5d1SDavid du Colombier 			}
14193e12c5d1SDavid du Colombier 		return 0;
14203e12c5d1SDavid du Colombier 	    out:
14213e12c5d1SDavid du Colombier 		if('0'<=s[strlen(greek[i])] && s[strlen(greek[i])]<='9')
14223e12c5d1SDavid du Colombier 			parsed[1]=s[strlen(greek[i])]-'0';
14233e12c5d1SDavid du Colombier 	}
14243e12c5d1SDavid du Colombier 	for(i=1; i<=88; i++)
14253e12c5d1SDavid du Colombier 		if(strcmp(constel[i], blank)==0){
14263e12c5d1SDavid du Colombier 			parsed[2] = i;
14273e12c5d1SDavid du Colombier 			return 1;
14283e12c5d1SDavid du Colombier 		}
14293e12c5d1SDavid du Colombier 	return 0;
14303e12c5d1SDavid du Colombier }
14313e12c5d1SDavid du Colombier 
1432219b2ee8SDavid du Colombier char*
dist_grp(int dg)1433219b2ee8SDavid du Colombier dist_grp(int dg)
1434219b2ee8SDavid du Colombier {
1435219b2ee8SDavid du Colombier 	switch(dg){
1436219b2ee8SDavid du Colombier 	default:
1437219b2ee8SDavid du Colombier 		return "unknown";
1438219b2ee8SDavid du Colombier 	case 1:
1439219b2ee8SDavid du Colombier 		return "13.3-14.0";
1440219b2ee8SDavid du Colombier 	case 2:
1441219b2ee8SDavid du Colombier 		return "14.1-14.8";
1442219b2ee8SDavid du Colombier 	case 3:
1443219b2ee8SDavid du Colombier 		return "14.9-15.6";
1444219b2ee8SDavid du Colombier 	case 4:
1445219b2ee8SDavid du Colombier 		return "15.7-16.4";
1446219b2ee8SDavid du Colombier 	case 5:
1447219b2ee8SDavid du Colombier 		return "16.5-17.2";
1448219b2ee8SDavid du Colombier 	case 6:
1449219b2ee8SDavid du Colombier 		return "17.3-18.0";
1450219b2ee8SDavid du Colombier 	case 7:
1451219b2ee8SDavid du Colombier 		return ">18.0";
1452219b2ee8SDavid du Colombier 	}
1453219b2ee8SDavid du Colombier }
1454219b2ee8SDavid du Colombier 
1455219b2ee8SDavid du Colombier char*
rich_grp(int dg)1456219b2ee8SDavid du Colombier rich_grp(int dg)
1457219b2ee8SDavid du Colombier {
1458219b2ee8SDavid du Colombier 	switch(dg){
1459219b2ee8SDavid du Colombier 	default:
1460219b2ee8SDavid du Colombier 		return "unknown";
1461219b2ee8SDavid du Colombier 	case 0:
1462219b2ee8SDavid du Colombier 		return "30-40";
1463219b2ee8SDavid du Colombier 	case 1:
1464219b2ee8SDavid du Colombier 		return "50-79";
1465219b2ee8SDavid du Colombier 	case 2:
1466219b2ee8SDavid du Colombier 		return "80-129";
1467219b2ee8SDavid du Colombier 	case 3:
1468219b2ee8SDavid du Colombier 		return "130-199";
1469219b2ee8SDavid du Colombier 	case 4:
1470219b2ee8SDavid du Colombier 		return "200-299";
1471219b2ee8SDavid du Colombier 	case 5:
1472219b2ee8SDavid du Colombier 		return ">=300";
1473219b2ee8SDavid du Colombier 	}
1474219b2ee8SDavid du Colombier }
14753e12c5d1SDavid du Colombier 
147659cc4ca5SDavid du Colombier char*
nameof(Record * r)147759cc4ca5SDavid du Colombier nameof(Record *r)
147859cc4ca5SDavid du Colombier {
147959cc4ca5SDavid du Colombier 	NGCrec *n;
148059cc4ca5SDavid du Colombier 	SAOrec *s;
148159cc4ca5SDavid du Colombier 	Abellrec *a;
148259cc4ca5SDavid du Colombier 	static char buf[128];
148359cc4ca5SDavid du Colombier 	int i;
148459cc4ca5SDavid du Colombier 
148559cc4ca5SDavid du Colombier 	switch(r->type){
148659cc4ca5SDavid du Colombier 	default:
148759cc4ca5SDavid du Colombier 		return nil;
148859cc4ca5SDavid du Colombier 	case SAO:
148959cc4ca5SDavid du Colombier 		s = &r->sao;
149059cc4ca5SDavid du Colombier 		if(s->name[0] == 0)
149159cc4ca5SDavid du Colombier 			return nil;
149259cc4ca5SDavid du Colombier 		if(s->name[0] >= 100){
149359cc4ca5SDavid du Colombier 			i = snprint(buf, sizeof buf, "%C", greeklet[s->name[0]-100]);
149459cc4ca5SDavid du Colombier 			if(s->name[1])
149559cc4ca5SDavid du Colombier 				i += snprint(buf+i, sizeof buf-i, "%d", s->name[1]);
149659cc4ca5SDavid du Colombier 		}else
149759cc4ca5SDavid du Colombier 			i = snprint(buf, sizeof buf, " %d", s->name[0]);
149859cc4ca5SDavid du Colombier 		snprint(buf+i, sizeof buf-i, " %s", constel[s->name[2]]);
149959cc4ca5SDavid du Colombier 		break;
150059cc4ca5SDavid du Colombier 	case NGC:
150159cc4ca5SDavid du Colombier 		n = &r->ngc;
150259cc4ca5SDavid du Colombier 		if(n->type >= Uncertain)
150359cc4ca5SDavid du Colombier 			return nil;
150459cc4ca5SDavid du Colombier 		if(n->ngc <= NNGC)
150559cc4ca5SDavid du Colombier 			snprint(buf, sizeof buf, "NGC%4d ", n->ngc);
150659cc4ca5SDavid du Colombier 		else
150759cc4ca5SDavid du Colombier 			snprint(buf, sizeof buf, "IC%4d ", n->ngc-NNGC);
150859cc4ca5SDavid du Colombier 		break;
150959cc4ca5SDavid du Colombier 	case Abell:
151059cc4ca5SDavid du Colombier 		a = &r->abell;
151159cc4ca5SDavid du Colombier 		snprint(buf, sizeof buf, "Abell%4d", a->abell);
151259cc4ca5SDavid du Colombier 		break;
151359cc4ca5SDavid du Colombier 	}
151459cc4ca5SDavid du Colombier 	return buf;
151559cc4ca5SDavid du Colombier }
151659cc4ca5SDavid du Colombier 
15173e12c5d1SDavid du Colombier void
prrec(Record * r)15183e12c5d1SDavid du Colombier prrec(Record *r)
15193e12c5d1SDavid du Colombier {
15203e12c5d1SDavid du Colombier 	NGCrec *n;
15213e12c5d1SDavid du Colombier 	SAOrec *s;
1522219b2ee8SDavid du Colombier 	Abellrec *a;
152359cc4ca5SDavid du Colombier 	Planetrec *p;
1524219b2ee8SDavid du Colombier 	int i, rah, ram, dec, nn;
15253e12c5d1SDavid du Colombier 	long key;
15263e12c5d1SDavid du Colombier 
15273e12c5d1SDavid du Colombier 	if(r) switch(r->type){
15283e12c5d1SDavid du Colombier 	default:
15293e12c5d1SDavid du Colombier 		fprint(2, "can't prrec type %d\n", r->type);
15303e12c5d1SDavid du Colombier 		exits("type");
15313e12c5d1SDavid du Colombier 
153259cc4ca5SDavid du Colombier 	case Planet:
153359cc4ca5SDavid du Colombier 		p = &r->planet;
153459cc4ca5SDavid du Colombier 		Bprint(&bout, "%s", p->name);
153559cc4ca5SDavid du Colombier 		Bprint(&bout, "\t%s %s",
153659cc4ca5SDavid du Colombier 			hms(angle(p->ra)),
153759cc4ca5SDavid du Colombier 			dms(angle(p->dec)));
153859cc4ca5SDavid du Colombier 		Bprint(&bout, " %3.2f° %3.2f°",
153959cc4ca5SDavid du Colombier 			p->az/(double)MILLIARCSEC, p->alt/(double)MILLIARCSEC);
154059cc4ca5SDavid du Colombier 		Bprint(&bout, " %s",
154159cc4ca5SDavid du Colombier 			ms(angle(p->semidiam)));
154259cc4ca5SDavid du Colombier 		if(r->index <= 1)
154359cc4ca5SDavid du Colombier 			Bprint(&bout, " %g", p->phase);
154459cc4ca5SDavid du Colombier 		Bprint(&bout, "\n");
154559cc4ca5SDavid du Colombier 		break;
154659cc4ca5SDavid du Colombier 
15473e12c5d1SDavid du Colombier 	case NGC:
15483e12c5d1SDavid du Colombier 		n = &r->ngc;
1549219b2ee8SDavid du Colombier 		if(n->ngc <= NNGC)
1550219b2ee8SDavid du Colombier 			Bprint(&bout, "NGC%4d ", n->ngc);
1551219b2ee8SDavid du Colombier 		else
1552219b2ee8SDavid du Colombier 			Bprint(&bout, "IC%4d ", n->ngc-NNGC);
1553219b2ee8SDavid du Colombier 		Bprint(&bout, "%s ", ngcstring(n->type));
15543e12c5d1SDavid du Colombier 		if(n->mag == UNKNOWNMAG)
15553e12c5d1SDavid du Colombier 			Bprint(&bout, "----");
15563e12c5d1SDavid du Colombier 		else
1557219b2ee8SDavid du Colombier 			Bprint(&bout, "%.1f%c", n->mag/10.0, n->magtype);
1558219b2ee8SDavid du Colombier 		Bprint(&bout, "\t%s %s\t%c%.1f'\n",
15593e12c5d1SDavid du Colombier 			hm(angle(n->ra)),
15603e12c5d1SDavid du Colombier 			dm(angle(n->dec)),
1561219b2ee8SDavid du Colombier 			n->diamlim,
1562219b2ee8SDavid du Colombier 			DEG(angle(n->diam))*60.);
1563219b2ee8SDavid du Colombier 		prdesc(n->desc, desctab, descindex);
1564219b2ee8SDavid du Colombier 		printnames(r);
1565219b2ee8SDavid du Colombier 		break;
1566219b2ee8SDavid du Colombier 
1567219b2ee8SDavid du Colombier 	case Abell:
1568219b2ee8SDavid du Colombier 		a = &r->abell;
1569219b2ee8SDavid du Colombier 		Bprint(&bout, "Abell%4d  %.1f %.2f° %dMpc", a->abell, a->mag10/10.0,
1570219b2ee8SDavid du Colombier 			DEG(angle(a->rad)), a->dist);
1571219b2ee8SDavid du Colombier 		Bprint(&bout, "\t%s %s\t%.2f %.2f\n",
1572219b2ee8SDavid du Colombier 			hm(angle(a->ra)),
1573219b2ee8SDavid du Colombier 			dm(angle(a->dec)),
1574219b2ee8SDavid du Colombier 			DEG(angle(a->glat)),
1575219b2ee8SDavid du Colombier 			DEG(angle(a->glong)));
1576219b2ee8SDavid du Colombier 		Bprint(&bout, "\tdist grp: %s  rich grp: %s  %d galaxies/°²\n",
1577219b2ee8SDavid du Colombier 			dist_grp(a->distgrp),
1578219b2ee8SDavid du Colombier 			rich_grp(a->richgrp),
1579219b2ee8SDavid du Colombier 			a->pop);
1580219b2ee8SDavid du Colombier 		printnames(r);
15813e12c5d1SDavid du Colombier 		break;
15823e12c5d1SDavid du Colombier 
15833e12c5d1SDavid du Colombier 	case SAO:
15843e12c5d1SDavid du Colombier 		s = &r->sao;
15853e12c5d1SDavid du Colombier 		Bprint(&bout, "SAO%6ld  ", r->index);
15863e12c5d1SDavid du Colombier 		if(s->mag==UNKNOWNMAG)
15873e12c5d1SDavid du Colombier 			Bprint(&bout, "---");
15883e12c5d1SDavid du Colombier 		else
15893e12c5d1SDavid du Colombier 			Bprint(&bout, "%.1f", s->mag/10.0);
15903e12c5d1SDavid du Colombier 		if(s->mpg==UNKNOWNMAG)
15913e12c5d1SDavid du Colombier 			Bprint(&bout, ",---");
15923e12c5d1SDavid du Colombier 		else
15933e12c5d1SDavid du Colombier 			Bprint(&bout, ",%.1f", s->mpg/10.0);
15943e12c5d1SDavid du Colombier 		Bprint(&bout, "  %s %s  %.4fs %.3f\"",
15953e12c5d1SDavid du Colombier 			hms(angle(s->ra)),
15963e12c5d1SDavid du Colombier 			dms(angle(s->dec)),
15973e12c5d1SDavid du Colombier 			DEG(angle(s->dra))*(4*60),
15983e12c5d1SDavid du Colombier 			DEG(angle(s->ddec))*(60*60));
15993e12c5d1SDavid du Colombier 		Bprint(&bout, "  %.3s %c %.2s %ld %d",
16003e12c5d1SDavid du Colombier 			s->spec, s->code, s->compid, s->hd, s->hdcode);
160159cc4ca5SDavid du Colombier 		if(s->name[0])
160259cc4ca5SDavid du Colombier 			Bprint(&bout, " \"%s\"", nameof(r));
16033e12c5d1SDavid du Colombier 		Bprint(&bout, "\n");
1604219b2ee8SDavid du Colombier 		printnames(r);
16053e12c5d1SDavid du Colombier 		break;
16063e12c5d1SDavid du Colombier 
16073e12c5d1SDavid du Colombier 	case Patch:
16083e12c5d1SDavid du Colombier 		radec(r->index, &rah, &ram, &dec);
16093e12c5d1SDavid du Colombier 		Bprint(&bout, "%dh%dm %d°", rah, ram, dec);
16103e12c5d1SDavid du Colombier 		key = r->patch.key[0];
16113e12c5d1SDavid du Colombier 		Bprint(&bout, " %s", constel[key&0xFF]);
16123e12c5d1SDavid du Colombier 		if((key>>=8) & 0xFF)
16133e12c5d1SDavid du Colombier 			Bprint(&bout, " %s", constel[key&0xFF]);
16143e12c5d1SDavid du Colombier 		if((key>>=8) & 0xFF)
16153e12c5d1SDavid du Colombier 			Bprint(&bout, " %s", constel[key&0xFF]);
16163e12c5d1SDavid du Colombier 		if((key>>=8) & 0xFF)
16173e12c5d1SDavid du Colombier 			Bprint(&bout, " %s", constel[key&0xFF]);
16183e12c5d1SDavid du Colombier 		for(i=1; i<r->patch.nkey; i++){
16193e12c5d1SDavid du Colombier 			key = r->patch.key[i];
1620219b2ee8SDavid du Colombier 			switch(key&0x3F){
1621219b2ee8SDavid du Colombier 			case SAO:
1622219b2ee8SDavid du Colombier 				Bprint(&bout, " SAO%ld", (key>>8)&0xFFFFFF);
1623219b2ee8SDavid du Colombier 				break;
1624219b2ee8SDavid du Colombier 			case Abell:
1625219b2ee8SDavid du Colombier 				Bprint(&bout, " Abell%ld", (key>>8)&0xFFFFFF);
1626219b2ee8SDavid du Colombier 				break;
1627219b2ee8SDavid du Colombier 			default:	/* NGC */
1628219b2ee8SDavid du Colombier 				nn = (key>>16)&0xFFFF;
1629219b2ee8SDavid du Colombier 				if(nn > NNGC)
16307dd7cddfSDavid du Colombier 					Bprint(&bout, " IC%d", nn-NNGC);
16313e12c5d1SDavid du Colombier 				else
16327dd7cddfSDavid du Colombier 					Bprint(&bout, " NGC%d", nn);
1633219b2ee8SDavid du Colombier 				Bprint(&bout, "(%s)", ngcstring(key&0x3F));
1634219b2ee8SDavid du Colombier 				break;
1635219b2ee8SDavid du Colombier 			}
16363e12c5d1SDavid du Colombier 		}
16373e12c5d1SDavid du Colombier 		Bprint(&bout, "\n");
16383e12c5d1SDavid du Colombier 		break;
16393e12c5d1SDavid du Colombier 
16403e12c5d1SDavid du Colombier 	case NGCN:
1641219b2ee8SDavid du Colombier 		if(r->index <= NNGC)
16427dd7cddfSDavid du Colombier 			Bprint(&bout, "NGC%ld\n", r->index);
1643219b2ee8SDavid du Colombier 		else
16447dd7cddfSDavid du Colombier 			Bprint(&bout, "IC%ld\n", r->index-NNGC);
16453e12c5d1SDavid du Colombier 		break;
16463e12c5d1SDavid du Colombier 
1647219b2ee8SDavid du Colombier 	case NamedSAO:
1648219b2ee8SDavid du Colombier 		Bprint(&bout, "SAO%ld \"%s\"\n", r->index, togreek(r->named.name));
1649219b2ee8SDavid du Colombier 		break;
1650219b2ee8SDavid du Colombier 
1651219b2ee8SDavid du Colombier 	case NamedNGC:
1652219b2ee8SDavid du Colombier 		if(r->index <= NNGC)
1653219b2ee8SDavid du Colombier 			Bprint(&bout, "NGC%ld \"%s\"\n", r->index, togreek(r->named.name));
1654219b2ee8SDavid du Colombier 		else
1655219b2ee8SDavid du Colombier 			Bprint(&bout, "IC%ld \"%s\"\n", r->index-NNGC, togreek(r->named.name));
1656219b2ee8SDavid du Colombier 		break;
1657219b2ee8SDavid du Colombier 
1658219b2ee8SDavid du Colombier 	case NamedAbell:
1659219b2ee8SDavid du Colombier 		Bprint(&bout, "Abell%ld \"%s\"\n", r->index, togreek(r->named.name));
16603e12c5d1SDavid du Colombier 		break;
16613e12c5d1SDavid du Colombier 
16623e12c5d1SDavid du Colombier 	case PatchC:
16633e12c5d1SDavid du Colombier 		radec(r->index, &rah, &ram, &dec);
16643e12c5d1SDavid du Colombier 		Bprint(&bout, "%dh%dm %d\n", rah, ram, dec);
16653e12c5d1SDavid du Colombier 		break;
16663e12c5d1SDavid du Colombier 	}
16673e12c5d1SDavid du Colombier }
1668