home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Education
/
collectionofeducationcarat1997.iso
/
SCIENCE
/
EPHEM421.ZIP
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-09-13
|
26KB
|
965 lines
/* main "ephem" program.
* -------------------------------------------------------------------
* Copyright (c) 1990 by Elwood Charles Downey
*
* Permission is granted to make and distribute copies of this program
* free of charge, provided the copyright notice and this permission
* notice are preserved on all copies. All other rights reserved.
* -------------------------------------------------------------------
* set options.
* init screen and circumstances.
* enter infinite loop updating screen and allowing operator input.
*/
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#ifdef VMS
#include <stdlib.h>
#endif
#include "astro.h"
#include "circum.h"
#include "screen.h"
extern char *strncpy();
extern char *getenv();
/* shorthands for fields of a Now structure, now.
* first undo the ones for a Now pointer from circum.h.
*/
#undef mjd
#undef lat
#undef lng
#undef tz
#undef temp
#undef pressure
#undef height
#undef epoch
#undef tznm
#define mjd now.n_mjd
#define lat now.n_lat
#define lng now.n_lng
#define tz now.n_tz
#define temp now.n_temp
#define pressure now.n_pressure
#define height now.n_height
#define epoch now.n_epoch
#define tznm now.n_tznm
static jmp_buf fpe_err_jmp; /* used to recover from SIGFPE */
static char *cfgfile; /* !0 if -c used */
static char cfgdef[] = "ephem.cfg"; /* default configuration file name */
static Now now; /* where when and how, right now */
static double tminc; /* hrs to inc time by each loop; RTC means use clock */
static int nstep; /* steps to go before stopping */
static int spause; /* secs to pause between steps */
static int optwi; /* set when want to display dawn/dusk/len-of-night */
static int oppl; /* mask of (1<<planet) bits; set when want to show it */
main (ac, av)
int ac;
char *av[];
{
void bye();
void on_fpe();
static char freerun[] =
"Running... press any key to stop to make changes.";
static char prmpt[] =
"Move to another field, RETURN to change this field, ? for help, or q to run";
static char hlp[] =
"arrow keys move to field; any key stops running; ^d exits; ^l redraws";
int curr = R_NSTEP, curc = C_NSTEPV; /* must start somewhere */
int sflag = 0; /* not silent, by default */
int one = 1; /* use a variable so optimizer doesn't get disabled */
int srchdone = 0; /* true when search funcs say so */
int newcir = 2; /* set when circumstances change - means don't tminc */
while ((--ac > 0) && (**++av == '-')) {
char *s;
for (s = *av+1; *s != '\0'; s++)
switch (*s) {
case 's': /* no credits "silent" (don't publish this) */
sflag++;
break;
case 'c': /* set name of config file to use */
if (--ac <= 0) usage("-c but no config file");
cfgfile = *++av;
break;
case 'd': /* set alternate database file name */
if (--ac <= 0) usage("-d but no database file");
obj_setdbfilename (*++av);
break;
default:
usage("Bad - option");
}
}
if (!sflag)
credits();
/* fresh screen.
* crack config file, THEN args so args may override.
*/
c_erase();
read_cfgfile ();
read_fieldargs (ac, av);
/* set up to clean up screen and tty if interrupted.
* also set up to stop if get floating error.
*/
(void) signal (SIGINT, bye);
(void) signal (SIGFPE, on_fpe);
/* update screen forever (until QUIT) */
while (one) {
/* if get a floating error, longjmp() here and stop looping */
if (setjmp (fpe_err_jmp))
nstep = 0;
else {
nstep -= 1;
/* recalculate everything and update all the fields */
redraw_screen (newcir);
mm_newcir (0);
/* let searching functions change tminc and check for done */
srchdone = srch_eval (mjd, &tminc) < 0;
print_tminc(0); /* to show possibly new search increment */
/* update plot and listing files, now that all fields are up
* to date and search function has been evaluated.
*/
plot();
listing();
/* handle spause if we are really looping */
if (nstep > 0)
slp_sync();
}
/* stop loop to allow op to change parameters:
* if a search evaluation converges (or errors out),
* or if steps are done,
* or if op hits any key.
*/
newcir = 0;
if (srchdone || nstep <= 0 || (chk_char()==0 && read_char()!=0)) {
int fld;
/* update screen with the current stuff if stopped during
* unattended plotting or listing since last redraw_screen()
* didn't.
*/
if ((plot_ison() || listing_ison()) && nstep > 0)
redraw_screen (1);
/* return nstep to default of 1 */
if (nstep <= 0) {
nstep = 1;
print_nstep (0);
}
/* change fields until END.
* update all time fields if any are changed
* and print NEW CIRCUMSTANCES if any have changed.
* QUIT causes bye() to be called and we never return.
*/
while(fld = sel_fld(curr,curc,alt_menumask()|F_CHG,prmpt,hlp)) {
if (chg_fld ((char *)0, fld)) {
mm_now (&now, 1);
mm_newcir(1);
newcir = 1;
}
curr = unpackr (fld);
curc = unpackc (fld);
}
if (nstep > 1)
f_prompt (freerun);
}
/* increment time only if op didn't change cirumstances */
if (!newcir)
inc_mjd (&now, tminc);
}
return (0);
}
/* read in ephem's configuration file, if any.
* if errors in file, call usage() (which exits).
* if use -d, require it; else try $EPHEMCFG and ephem.cfg but don't
* complain if can't find these since, after all, one is not required.
* skip blank lines and lines that begin with '#', '*', ' ' or '\t'.
*/
static
read_cfgfile()
{
char buf[128];
FILE *fp;
char *fn;
/* open the config file.
* only REQUIRED if used -d option.
* if succcessful, fn points to file name.
*/
if (cfgfile) {
fn = cfgfile;
fp = fopen (fn, "r");
if (!fp) {
(void) sprintf (buf, "Can not open %s", fn);
usage (buf); /* does not return */
}
} else {
fn = getenv ("EPHEMCFG");
if (!fn)
fn = cfgdef;
}
fp = fopen (fn, "r");
if (!fp)
return; /* oh well; after all, it's not required */
while (fgets (buf, sizeof(buf), fp)) {
switch (buf[0]) {
case '#': case '*': case ' ': case '\t': case '\n':
continue;
}
buf[strlen(buf)-1] = '\0'; /* discard trailing \n */
if (crack_fieldset (buf) < 0) {
char why[NC];
(void) sprintf (why, "Bad field spec in %s: %s\n", fn, buf);
usage (why);
}
}
(void) fclose (fp);
}
/* draw all the stuff on the screen, using the current menu.
* if how_much == 0 then just update fields that need it;
* if how_much == 1 then redraw all fields;
* if how_much == 2 then erase the screen and redraw EVERYTHING.
*/
redraw_screen (how_much)
int how_much;
{
if (how_much == 2)
c_erase();
/* print the single-step message if this is the last loop */
if (nstep < 1)
print_updating();
if (how_much == 2) {
mm_borders();
mm_labels();
srch_prstate(1);
plot_prstate(1);
listing_prstate(1);
alt_labels();
}
/* if just updating changed fields while plotting or listing
* unattended then suppress most screen updates except
* always show nstep to show plot loops to go and
* always show tminc to show search convergence progress.
*/
print_nstep(how_much);
print_tminc(how_much);
print_spause(how_much);
if (how_much == 0 && (plot_ison() || listing_ison()) && nstep > 0)
f_off();
/* print all the time-related fields */
mm_now (&now, how_much);
if (optwi)
mm_twilight (&now, how_much);
/* print solar system body info */
print_bodies (how_much);
f_on();
}
/* clean up and exit.
*/
void
bye()
{
c_erase();
byetty();
exit (0);
}
/* this gets called when a floating point error occurs.
* we force a jump back into main() with looping terminated.
*/
static
void
on_fpe()
{
(void) signal (SIGFPE, on_fpe);
f_msg ("Floating point error has occurred - computations aborted.");
longjmp (fpe_err_jmp, 1);
}
us