home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume19 / xephem / part19 < prev    next >
Encoding:
Text File  |  1993-05-15  |  76.6 KB  |  2,780 lines

  1. Newsgroups: comp.sources.x
  2. From: ecdowney@pobox.cca.cr.rockwell.com (Elwood Downey)
  3. Subject: v19i107:  xephem - astronomical ephemeris program, Part19/21
  4. Message-ID: <1993May10.221325.9664@sparky.imd.sterling.com>
  5. X-Md4-Signature: 3ebabe619858e48d6fcc3b6b6f754654
  6. Date: Mon, 10 May 1993 22:13:25 GMT
  7. Approved: chris@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ecdowney@pobox.cca.cr.rockwell.com (Elwood Downey)
  10. Posting-number: Volume 19, Issue 107
  11. Archive-name: xephem/part19
  12. Environment: X11r4, OSF/Motif
  13. Supersedes: xephem: Volume 16, Issue 112-134
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  anomaly.c compiler.c db.c plans.c skyfiltmenu.c
  22. # Wrapped by chris@nova on Mon May 10 16:41:53 1993
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 19 (of 21)."'
  26. if test -f 'anomaly.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'anomaly.c'\"
  28. else
  29.   echo shar: Extracting \"'anomaly.c'\" \(905 characters\)
  30.   sed "s/^X//" >'anomaly.c' <<'END_OF_FILE'
  31. X#include <stdio.h>
  32. X#include <math.h>
  33. X#include "astro.h"
  34. X
  35. X#define    TWOPI    (2*PI)
  36. X
  37. X/* given the mean anomaly, ma, and the eccentricity, s, of elliptical motion,
  38. X * find the true anomaly, *nu, and the eccentric anomaly, *ea.
  39. X * all angles in radians.
  40. X */
  41. Xvoid
  42. Xanomaly (ma, s, nu, ea)
  43. Xdouble ma, s;
  44. Xdouble *nu, *ea;
  45. X{
  46. X    double m, fea;
  47. X
  48. X    m = ma-TWOPI*(long)(ma/TWOPI);
  49. X    if (m > PI) m -= TWOPI;
  50. X    if (m < -PI) m += TWOPI;
  51. X    fea = m;
  52. X
  53. X    if (s < 1.0) {
  54. X        /* elliptical */
  55. X        double dla;
  56. X        for (;;) {
  57. X        dla = fea-(s*sin(fea))-m;
  58. X        if (fabs(dla)<1e-6)
  59. X            break;
  60. X        dla /= 1-(s*cos(fea));
  61. X        fea -= dla;
  62. X        }
  63. X        *nu = 2*atan(sqrt((1+s)/(1-s))*tan(fea/2));
  64. X        } else {
  65. X        /* hyperbolic */
  66. X        double corr = 1;
  67. X        while (fabs(corr) > 0.000001) {
  68. X          corr = (m - s * sinh(fea) + fea) / (s*cosh(fea) - 1);
  69. X          fea += corr;
  70. X        }
  71. X        *nu = 2*atan(sqrt((s+1)/(s-1))*tanh(fea/2));
  72. X    }
  73. X    *ea = fea;
  74. X}
  75. END_OF_FILE
  76.   if test 905 -ne `wc -c <'anomaly.c'`; then
  77.     echo shar: \"'anomaly.c'\" unpacked with wrong size!
  78.   fi
  79.   # end of 'anomaly.c'
  80. fi
  81. if test -f 'compiler.c' -a "${1}" != "-c" ; then 
  82.   echo shar: Will not clobber existing file \"'compiler.c'\"
  83. else
  84.   echo shar: Extracting \"'compiler.c'\" \(16650 characters\)
  85.   sed "s/^X//" >'compiler.c' <<'END_OF_FILE'
  86. X/* module to compile and execute a c-style arithmetic expression.
  87. X * public entry points are compile_expr() and execute_expr().
  88. X * 
  89. X * field names are defined to be anything in double quotes when compiling.
  90. X * the compiler will build a table of names it sees; indexes into this table
  91. X * are part of the opcode. Field names are resolved when the expression is
  92. X * evaluated to avoid restricting when the fields are named and defined.
  93. X *
  94. X * one reason this is so nice and tight is that all opcodes are the same size
  95. X * (an int) and the tokens the parser returns are directly usable as opcodes.
  96. X * constants and variables are compiled as an opcode with an offset into the
  97. X *  auxiliary consts and vars arrays.
  98. X */
  99. X
  100. X#include <stdio.h>
  101. X#include <math.h>
  102. X#include <ctype.h>
  103. X#if defined(__STDC__)
  104. X#include <stdlib.h>
  105. X#endif
  106. X#include <X11/Xlib.h>
  107. X#include <Xm/Xm.h>
  108. X
  109. X#if defined(__STDC__) || defined(__cplusplus)
  110. X#define P_(s) s
  111. X#else
  112. X#define P_(s) ()
  113. X#endif
  114. X
  115. Xint compile_expr P_((char *ex, char *errbuf));
  116. Xint execute_expr P_((double *vp, char *errbuf));
  117. Xint prog_isgood P_((void));
  118. Xvoid compiler_log P_((char *name, double value));
  119. Xstatic next_token P_((void));
  120. Xstatic chk_funcs P_((void));
  121. Xstatic void skip_double P_((void));
  122. Xstatic compile P_((int prec));
  123. Xstatic execute P_((double *result));
  124. Xstatic parse_fieldname P_((char name[], int len));
  125. X
  126. X#undef P_
  127. X
  128. X/* parser tokens and opcodes, as necessary */
  129. X#define    HALT    0    /* good value for HALT since program is inited to 0 */
  130. X/* binary operators (precedences in table, below) */
  131. X#define    ADD    1
  132. X#define    SUB    2
  133. X#define    MULT    3
  134. X#define    DIV    4
  135. X#define    AND    5
  136. X#define    OR    6
  137. X#define    GT    7
  138. X#define    GE    8
  139. X#define    EQ    9
  140. X#define    NE    10
  141. X#define    LT    11
  142. X#define    LE    12
  143. X/* unary op, precedence in NEG_PREC #define, below */
  144. X#define    NEG    13
  145. X/* symantically operands, ie, constants, variables and all functions */
  146. X#define    CONST    14    
  147. X#define    VAR    15
  148. X#define    ABS    16    /* add functions if desired just like this is done */
  149. X#define    SIN    17
  150. X#define    COS    18
  151. X#define    TAN    19
  152. X#define    ASIN    20
  153. X#define    ACOS    21
  154. X#define    ATAN    22
  155. X#define    PITOK    23    /* built-in constant, pi */
  156. X#define    DEGRAD    24
  157. X#define    RADDEG    25
  158. X#define    LOG    26
  159. X#define    LOG10    27
  160. X#define    EXP    28
  161. X#define    SQRT    29
  162. X#define    POW    30
  163. X#define    ATAN2    31
  164. X/* purely tokens - never get compiled as such */
  165. X#define    LPAREN    255
  166. X#define    RPAREN    254
  167. X#define    COMMA    253
  168. X#define    ERR    (-1)
  169. X
  170. X/* precedence of each of the binary operators.
  171. X * in case of a tie, compiler associates left-to-right.
  172. X * N.B. each entry's index must correspond to its #define!
  173. X */
  174. Xstatic int precedence[] = {0,5,5,6,6,2,1,4,4,3,3,4,4};
  175. X#define    NEG_PREC    7    /* negation is highest */
  176. X
  177. X/* execute-time operand stack */
  178. X#define    MAX_STACK    16
  179. Xstatic double stack[MAX_STACK], *sp;
  180. X
  181. X/* space for compiled opcodes - the "program".
  182. X * opcodes go in lower 8 bits.
  183. X * when an opcode has an operand (as CONST and VAR) it is really an array
  184. X *   index in the remaining upper bits.
  185. X */
  186. X#define    MAX_PROG 32
  187. Xstatic int program[MAX_PROG], *pc;
  188. X#define    OP_SHIFT    8
  189. X#define    OP_MASK        0xff
  190. X
  191. X/* auxiliary operand info.
  192. X * the operands (all but lower 8 bits) of CONST and VAR are really indeces
  193. X * into these arrays. thus, no point in making them any longer than you have
  194. X * bits more than 8 in your machine's int to index into it, ie, make
  195. X *    MAX_OPX <= 1 << ((sizeof(int)-1)*8)
  196. X */
  197. X#define    MAX_OPX        16
  198. X#define    MAXFLDLEN    32    /* longest allowed field name */
  199. Xtypedef struct {
  200. X    char v_name[MAXFLDLEN];    /* name of field */
  201. X    double v_v;            /* last known value of this field */
  202. X} Var;
  203. Xstatic Var vars[MAX_OPX];
  204. Xstatic int nvars;        /* number of vars[] in actual use */
  205. Xstatic double consts[MAX_OPX];
  206. Xstatic int nconsts;        /* number of consts[] in actual use */
  207. X
  208. X
  209. X/* these are global just for easy/rapid access */
  210. Xstatic int parens_nest;    /* to check that parens end up nested */
  211. Xstatic char *err_msg;    /* caller provides storage; we point at it with this */
  212. Xstatic char *cexpr, *lcexpr; /* pointers that move along caller's expression */
  213. Xstatic int good_prog;    /* != 0 when program appears to be good */
  214. X
  215. X/* compile the given c-style expression.
  216. X * return 0 and set good_prog if ok,
  217. X * else return -1 and a reason message in errbuf.
  218. X */
  219. Xcompile_expr (ex, errbuf)
  220. Xchar *ex;
  221. Xchar *errbuf;
  222. X{
  223. X    /* init the globals.
  224. X     * also delete any flogs used in the previous program.
  225. X     */
  226. X    cexpr = ex;
  227. X    err_msg = errbuf;
  228. X    pc = program;
  229. X    nvars = nconsts = 0;
  230. X    parens_nest = 0;
  231. X
  232. X    pc = program;
  233. X    if (compile(0) == ERR) {
  234. X        (void) sprintf (err_msg + strlen(err_msg), " near `%.10s'", lcexpr);
  235. X        good_prog = 0;
  236. X        return (-1);
  237. X    }
  238. X    if (pc == program) {
  239. X        (void) sprintf (err_msg, "null program");
  240. X        good_prog = 0;
  241. X        return (-1);
  242. X    }
  243. X    *pc++ = HALT;
  244. X    good_prog = 1;
  245. X    return (0);
  246. X}
  247. X
  248. X/* execute the expression previously compiled with compile_expr().
  249. X * return 0 with *vp set to the answer if ok, else return -1 with a reason
  250. X * why not message in errbuf.
  251. X */
  252. Xexecute_expr (vp, errbuf)
  253. Xdouble *vp;
  254. Xchar *errbuf;
  255. X{
  256. X    int s;
  257. X
  258. X    err_msg = errbuf;
  259. X    sp = stack + MAX_STACK;    /* grows towards lower addresses */
  260. X    pc = program;
  261. X    s = execute(vp);
  262. X    if (s < 0)
  263. X        good_prog = 0;
  264. X    return (s);
  265. X}
  266. X
  267. X/* this is a way for the outside world to ask whether there is currently a
  268. X * reasonable program compiled and able to execute.
  269. X */
  270. Xprog_isgood()
  271. X{
  272. X    return (good_prog);
  273. X}
  274. X
  275. X/* called when each different field is written.
  276. X * this is just called by srch_log() to hide the fact from users of srch*
  277. X * that srch is really using our vars array to store values.
  278. X * since this gets called for all fields, it's not an error to not find name.
  279. X * don't stop when see the first one because a term might appear more than once.
  280. X */
  281. Xvoid
  282. Xcompiler_log (name, value)
  283. Xchar *name;
  284. Xdouble value;
  285. X{
  286. X    Var *vp;
  287. X
  288. X    for (vp = vars; vp < &vars[nvars]; vp++)
  289. X        if (vp->v_name && strcmp (vp->v_name, name) == 0)
  290. X        vp->v_v = value;
  291. X}
  292. X
  293. X/* get and return the opcode corresponding to the next token.
  294. X * leave with lcexpr pointing at the new token, cexpr just after it.
  295. X * also watch for mismatches parens and proper operator/operand alternation.
  296. X */
  297. Xstatic
  298. Xnext_token ()
  299. X{
  300. X    static char toomv[] = "More than %d variables";
  301. X    static char toomc[] = "More than %d constants";
  302. X    static char badop[] = "Illegal operator";
  303. X    int tok = ERR;    /* just something illegal */
  304. X    char c;
  305. X
  306. X    while ((c = *cexpr) == ' ')
  307. X        cexpr++;
  308. X    lcexpr = cexpr++;
  309. X
  310. X    /* mainly check for a binary operator */
  311. X    switch (c) {
  312. X    case ',': tok = COMMA; break;
  313. X    case '\0': --cexpr; tok = HALT; break; /* keep returning HALT */
  314. X    case '+': tok = ADD; break; /* compiler knows when it's really unary */
  315. X    case '-': tok = SUB; break; /* compiler knows when it's really negate */
  316. X    case '*': tok = MULT; break;
  317. X    case '/': tok = DIV; break;
  318. X    case '(': parens_nest++; tok = LPAREN; break;
  319. X    case ')':
  320. X        if (--parens_nest < 0) {
  321. X            (void) sprintf (err_msg, "Too many right parens");
  322. X        return (ERR);
  323. X        } else
  324. X        tok = RPAREN;
  325. X        break;
  326. X    case '|':
  327. X        if (*cexpr == '|') { cexpr++; tok = OR; }
  328. X        else { (void) sprintf (err_msg, badop); return (ERR); }
  329. X        break;
  330. X    case '&':
  331. X        if (*cexpr == '&') { cexpr++; tok = AND; }
  332. X        else { (void) sprintf (err_msg, badop); return (ERR); }
  333. X        break;
  334. X    case '=':
  335. X        if (*cexpr == '=') { cexpr++; tok = EQ; }
  336. X        else { (void) sprintf (err_msg, badop); return (ERR); }
  337. X        break;
  338. X    case '!':
  339. X        if (*cexpr == '=') { cexpr++; tok = NE; }
  340. X        else { (void) sprintf (err_msg, badop); return (ERR); }
  341. X        break;
  342. X    case '<':
  343. X        if (*cexpr == '=') { cexpr++; tok = LE; }
  344. X        else tok = LT;
  345. X        break;
  346. X    case '>':
  347. X        if (*cexpr == '=') { cexpr++; tok = GE; }
  348. X        else tok = GT;
  349. X        break;
  350. X    }
  351. X
  352. X    if (tok != ERR)
  353. X        return (tok);
  354. X
  355. X    /* not op so check for a constant, variable or function */
  356. X    if (isdigit(c) || c == '.') {
  357. X        /* looks like a constant.
  358. X         * leading +- already handled
  359. X         */
  360. X        if (nconsts > MAX_OPX) {
  361. X        (void) sprintf (err_msg, toomc, MAX_OPX);
  362. X        return (ERR);
  363. X        }
  364. X        consts[nconsts] = atof (lcexpr);
  365. X        tok = CONST | (nconsts++ << OP_SHIFT);
  366. X        skip_double();
  367. X    } else if (isalpha(c)) {
  368. X        /* check list of functions */
  369. X        tok = chk_funcs();
  370. X        if (tok == ERR) {
  371. X        (void) sprintf (err_msg, "bad function");
  372. X        return (ERR);
  373. X        }
  374. X    } else if (c == '"') {
  375. X        /* a variable */
  376. X        if (nvars > MAX_OPX) {
  377. X        (void) sprintf (err_msg, toomv, MAX_OPX);
  378. X        return (ERR);
  379. X        }
  380. X        if (parse_fieldname (vars[nvars].v_name, MAXFLDLEN) < 0) {
  381. X        (void) sprintf (err_msg, "bad field");
  382. X        return (ERR);
  383. X        } else
  384. X        tok = VAR | (nvars++ << OP_SHIFT);
  385. X    }
  386. X
  387. X    if (tok != ERR)
  388. X        return (tok);
  389. X
  390. X    /* what the heck is it? */
  391. X    (void) sprintf (err_msg, "syntax error");
  392. X    return (ERR);
  393. X}
  394. X
  395. X/* return funtion token, else ERR.
  396. X * if find one, update cexpr too.
  397. X */
  398. Xstatic
  399. Xchk_funcs()
  400. X{
  401. X    static struct {
  402. X        char *st_name;
  403. X        int st_tok;
  404. X    } symtab[] = {
  405. X         /* be sure to put short names AFTER longer ones */
  406. X         {"abs", ABS},     {"acos", ACOS},   {"asin", ASIN},
  407. X         {"atan2", ATAN2},     {"atan", ATAN},   {"cos", COS},
  408. X         {"degrad", DEGRAD}, {"exp", EXP},       {"log10", LOG10},
  409. X         {"log", LOG},     {"pi", PITOK},       {"pow", POW},
  410. X         {"raddeg", RADDEG}, {"sin", SIN},       {"sqrt", SQRT},
  411. X         {"tan", TAN}
  412. X    };
  413. X    int i;
  414. X
  415. X    for (i = 0; i < sizeof(symtab)/sizeof(symtab[0]); i++) {
  416. X        int l = strlen (symtab[i].st_name);
  417. X        if (strncmp (lcexpr, symtab[i].st_name, l) == 0) {
  418. X        cexpr += l-1;
  419. X        return (symtab[i].st_tok);
  420. X        }
  421. X    }
  422. X    return (ERR);
  423. X}
  424. X
  425. X/* move cexpr on past a double.
  426. X * allow sci notation.
  427. X * no need to worry about a leading '-' or '+' but allow them after an 'e'.
  428. X * TODO: this handles all the desired cases, but also admits a bit too much
  429. X *   such as things like 1eee2...3. geeze; to skip a double right you almost
  430. X *   have to go ahead and crack it!
  431. X */
  432. Xstatic void
  433. Xskip_double()
  434. X{
  435. X    int sawe = 0;    /* so we can allow '-' or '+' right after an 'e' */
  436. X
  437. X    for (;;) {
  438. X        char c = *cexpr;
  439. X        if (isdigit(c) || c=='.' || (sawe && (c=='-' || c=='+'))) {
  440. X        sawe = 0;
  441. X        cexpr++;
  442. X        } else if (c == 'e') {
  443. X        sawe = 1;
  444. X        cexpr++;
  445. X        } else
  446. X        break;
  447. X    }
  448. X}
  449. X
  450. X/* call this whenever you want to dig out the next (sub)expression.
  451. X * keep compiling instructions as long as the operators are higher precedence
  452. X * than prec (or until see HALT, COMMA or RPAREN) then return that
  453. X * "look-ahead" token.
  454. X * if error, fill in a message in err_msg[] and return ERR.
  455. X */
  456. Xstatic
  457. Xcompile (prec)
  458. Xint prec;
  459. X{
  460. X    int expect_binop = 0;    /* set after we have seen any operand.
  461. X                 * used by SUB so it can tell if it really 
  462. X                 * should be taken to be a NEG instead.
  463. X                 */
  464. X    int tok = next_token ();
  465. X    int *oldpc;
  466. X
  467. X    for (;;) {
  468. X        int p;
  469. X        if (tok == ERR)
  470. X        return (ERR);
  471. X        if (pc - program >= MAX_PROG) {
  472. X        (void) sprintf (err_msg, "program is too long");
  473. X        return (ERR);
  474. X        }
  475. X
  476. X        /* check for special things like functions, constants and parens */
  477. X            switch (tok & OP_MASK) {
  478. X        case COMMA: return (tok);
  479. X            case HALT: return (tok);
  480. X        case ADD:
  481. X        if (expect_binop)
  482. X            break;    /* procede with binary addition */
  483. X        /* just skip a unary positive(?) */
  484. X        tok = next_token();
  485. X        if (tok == HALT) {
  486. X            (void) sprintf (err_msg, "term expected");
  487. X            return (ERR);
  488. X        }
  489. X        continue;
  490. X        case SUB:
  491. X        if (expect_binop)
  492. X            break;    /* procede with binary subtract */
  493. X        oldpc = pc;
  494. X        tok = compile (NEG_PREC);
  495. X        if (oldpc == pc) {
  496. X            (void) sprintf (err_msg, "term expected");
  497. X            return (ERR);
  498. X        }
  499. X        *pc++ = NEG;
  500. X        expect_binop = 1;
  501. X        continue;
  502. X        /* one-arg functions */
  503. X            case ABS: case SIN: case COS: case TAN: case ASIN: case ACOS:
  504. X        case ATAN: case DEGRAD: case RADDEG: case LOG: case LOG10:
  505. X        case EXP: case SQRT:
  506. X        /* eat up the function's parenthesized argument */
  507. X        if (next_token() != LPAREN) {
  508. X            (void) sprintf (err_msg, "saw a built-in function: expecting (");
  509. X            return (ERR);
  510. X        }
  511. X        oldpc = pc;
  512. X        if (compile (0) != RPAREN || oldpc == pc) {
  513. X            (void) sprintf (err_msg, "1-arg function arglist error");
  514. X            return (ERR);
  515. X        }
  516. X        *pc++ = tok;
  517. X        tok = next_token();
  518. X        expect_binop = 1;
  519. X        continue;
  520. X        /* two-arg functions */
  521. X        case POW: case ATAN2:
  522. X        /* eat up the function's parenthesized arguments */
  523. X        if (next_token() != LPAREN) {
  524. X            (void) sprintf (err_msg, "saw a built-in function: expecting (");
  525. X            return (ERR);
  526. X        }
  527. X        oldpc = pc;
  528. X        if (compile (0) != COMMA || oldpc == pc) {
  529. X            (void) sprintf (err_msg, "1st of 2-arg function arglist error");
  530. X            return (ERR);
  531. X        }
  532. X        oldpc = pc;
  533. X        if (compile (0) != RPAREN || oldpc == pc) {
  534. X            (void) sprintf (err_msg, "2nd of 2-arg function arglist error");
  535. X            return (ERR);
  536. X        }
  537. X        *pc++ = tok;
  538. X        tok = next_token();
  539. X        expect_binop = 1;
  540. X        continue;
  541. X        /* constants and variables are just like 0-arg functions w/o ()'s */
  542. X            case CONST:
  543. X        case PITOK:
  544. X        case VAR:
  545. X        *pc++ = tok;
  546. X        tok = next_token();
  547. X        expect_binop = 1;
  548. X        continue;
  549. X            case LPAREN:
  550. X        oldpc = pc;
  551. X        if (compile (0) != RPAREN) {
  552. X            (void) sprintf (err_msg, "unmatched left paren");
  553. X            return (ERR);
  554. X        }
  555. X        if (oldpc == pc) {
  556. X            (void) sprintf (err_msg, "null expression");
  557. X            return (ERR);
  558. X        }
  559. X        tok = next_token();
  560. X        expect_binop = 1;
  561. X        continue;
  562. X            case RPAREN:
  563. X        return (RPAREN);
  564. X            }
  565. X
  566. X        /* everything else is a binary operator */
  567. X        p = precedence[tok];
  568. X            if (p > prec) {
  569. X                int newtok;
  570. X        oldpc = pc;
  571. X                newtok = compile (p);
  572. X        if (newtok == ERR)
  573. X            return (ERR);
  574. X        if (oldpc == pc) {
  575. X            (void) strcpy (err_msg, "term or factor expected");
  576. X            return (ERR);
  577. X        }
  578. X                *pc++ = tok;
  579. X        expect_binop = 1;
  580. X                tok = newtok;
  581. X            } else
  582. X                return (tok);
  583. X        }
  584. X}
  585. X
  586. X/* "run" the program[] compiled with compile().
  587. X * if ok, return 0 and the final result,
  588. X * else return -1 with a reason why not message in err_msg.
  589. X */
  590. Xstatic
  591. Xexecute(result)
  592. Xdouble *result;
  593. X{
  594. X    int instr; 
  595. X
  596. X    do {
  597. X        instr = *pc++;
  598. X        switch (instr & OP_MASK) {
  599. X        /* put these in numberic order so hopefully even the dumbest
  600. X         * compiler will choose to use a jump table, not a cascade of ifs.
  601. X         */
  602. X        case HALT:    break;    /* outer loop will stop us */
  603. X        case ADD:    sp[1] = sp[1] +  sp[0]; sp++; break;
  604. X        case SUB:    sp[1] = sp[1] -  sp[0]; sp++; break;
  605. X        case MULT:    sp[1] = sp[1] *  sp[0]; sp++; break;
  606. X        case DIV:    sp[1] = sp[1] /  sp[0]; sp++; break;
  607. X        case AND:    sp[1] = sp[1] && sp[0] ? 1 : 0; sp++; break;
  608. X        case OR:    sp[1] = sp[1] || sp[0] ? 1 : 0; sp++; break;
  609. X        case GT:    sp[1] = sp[1] >  sp[0] ? 1 : 0; sp++; break;
  610. X        case GE:    sp[1] = sp[1] >= sp[0] ? 1 : 0; sp++; break;
  611. X        case EQ:    sp[1] = sp[1] == sp[0] ? 1 : 0; sp++; break;
  612. X        case NE:    sp[1] = sp[1] != sp[0] ? 1 : 0; sp++; break;
  613. X        case LT:    sp[1] = sp[1] <  sp[0] ? 1 : 0; sp++; break;
  614. X        case LE:    sp[1] = sp[1] <= sp[0] ? 1 : 0; sp++; break;
  615. X        case NEG:    *sp = -*sp; break;
  616. X        case CONST:    *--sp = consts[instr >> OP_SHIFT]; break;
  617. X        case VAR:    *--sp = vars[instr>>OP_SHIFT].v_v; break;
  618. X        case PITOK:    *--sp = 4.0*atan(1.0); break;
  619. X        case ABS:    *sp = fabs (*sp); break;
  620. X        case SIN:    *sp = sin (*sp); break;
  621. X        case COS:    *sp = cos (*sp); break;
  622. X        case TAN:    *sp = tan (*sp); break;
  623. X        case ASIN:    *sp = asin (*sp); break;
  624. X        case ACOS:    *sp = acos (*sp); break;
  625. X        case ATAN:    *sp = atan (*sp); break;
  626. X        case DEGRAD:*sp *= atan(1.0)/45.0; break;
  627. X        case RADDEG:*sp *= 45.0/atan(1.0); break;
  628. X        case LOG:    *sp = log (*sp); break;
  629. X        case LOG10:    *sp = log10 (*sp); break;
  630. X        case EXP:    *sp = exp (*sp); break;
  631. X        case SQRT:    *sp = sqrt (*sp); break;
  632. X        case POW:    sp[1] = pow (sp[1], sp[0]); sp++; break;
  633. X        case ATAN2:    sp[1] = atan2 (sp[1], sp[0]); sp++; break;
  634. X        default:
  635. X        (void) sprintf (err_msg, "Bug! bad opcode: 0x%x", instr);
  636. X        return (-1);
  637. X        }
  638. X        if (sp < stack) {
  639. X        (void) sprintf (err_msg, "Runtime stack overflow");
  640. X        return (-1);
  641. X        } else if (sp - stack > MAX_STACK) {
  642. X        (void) sprintf (err_msg, "Bug! runtime stack underflow");
  643. X        return (-1);
  644. X        }
  645. X    } while (instr != HALT);
  646. X
  647. X    /* result should now be on top of stack */
  648. X    if (sp != &stack[MAX_STACK - 1]) {
  649. X        (void) sprintf (err_msg, "Bug! stack has %d items",
  650. X                            MAX_STACK - (sp-stack));
  651. X        return (-1);
  652. X    }
  653. X    *result = *sp;
  654. X    return (0);
  655. X}
  656. X
  657. X/* starting with lcexpr pointing at a string expected to be a field name,
  658. X * ie, at a '"', fill into up to the next '"' into name[], including trailing 0.
  659. X * if there IS no '"' within len-1 chars, return -1, else 0.
  660. X * when return, leave lcexpr alone but move cexpr to just after the second '"'.
  661. X */
  662. Xstatic
  663. Xparse_fieldname (name, len)
  664. Xchar name[];
  665. Xint len;
  666. X{
  667. X    char c;
  668. X
  669. X    cexpr = lcexpr + 1;
  670. X    while (--len > 0 && (c = *cexpr++) != '"' && c)
  671. X        *name++ = c;
  672. X    if (len == 0 || c != '"')
  673. X        return (-1);
  674. X    *name = '\0';
  675. X    return (0);
  676. X}
  677. END_OF_FILE
  678.   if test 16650 -ne `wc -c <'compiler.c'`; then
  679.     echo shar: \"'compiler.c'\" unpacked with wrong size!
  680.   fi
  681.   # end of 'compiler.c'
  682. fi
  683. if test -f 'db.c' -a "${1}" != "-c" ; then 
  684.   echo shar: Will not clobber existing file \"'db.c'\"
  685. else
  686.   echo shar: Extracting \"'db.c'\" \(18368 characters\)
  687.   sed "s/^X//" >'db.c' <<'END_OF_FILE'
  688. X/* code to manage what the outside world sees as the db_ interface.
  689. X */
  690. X
  691. X#include <stdio.h>
  692. X#include <ctype.h>
  693. X#include <malloc.h>
  694. X#include <math.h>
  695. X#if defined(__STDC__)
  696. X#include <stdlib.h>
  697. X#include <string.h>
  698. X#endif
  699. X#include "astro.h"
  700. X#include "circum.h"
  701. X#include "preferences.h"
  702. X
  703. X
  704. X#if defined(__STDC__) || defined(__cplusplus)
  705. X#define P_(s) s
  706. X#else
  707. X#define P_(s) ()
  708. X#endif
  709. X
  710. Xextern Now *mm_get_now P_((void));
  711. Xextern int obj_cir P_((Now *np, Obj *op));
  712. Xextern void cal_mjd P_((int mn, double dy, int yr, double *Mjd));
  713. Xextern void f_dec_sexsign P_((double x, int *h, int *m, int *s));
  714. Xextern void f_sscandate P_((char *bp, int pref, int *m, double *d, int *y));
  715. Xextern void f_sscansex P_((char *bp, int *d, int *m, int *s));
  716. Xextern void mjd_cal P_((double Mjd, int *mn, double *dy, int *yr));
  717. Xextern void sex_dec P_((int hd, int m, int s, double *d));
  718. Xextern void xe_msg P_((char *msg, int app_modal));
  719. Xextern void zero_mem P_((char *loc, unsigned len));
  720. X
  721. Xint db_n P_((void));
  722. XObj *db_basic P_((int id));
  723. Xvoid db_setuserobj P_((int id, Obj *op));
  724. Xvoid db_invalidate P_((void));
  725. XObj *db_next P_((Obj *op, HowNext how));
  726. Xvoid db_update P_((Obj *op));
  727. Xint db_read P_((FILE *fp, int append));
  728. Xint db_set_field P_((char bp[], int id, PrefDateFormat pref, Obj *op));
  729. Xstatic Obj *db_new P_((int t));
  730. Xstatic db_crack_line P_((char *s));
  731. Xstatic void db_init P_((void));
  732. Xstatic int nxt_db P_((char buf[], int blen, FILE *fp));
  733. Xstatic void crack_year P_((char *bp, PrefDateFormat pref, double *p));
  734. X/* don't know why but my compiler complains with this one in here
  735. Xstatic get_fields P_((char *s, char delim, char *fields[]));
  736. X*/
  737. Xstatic get_fields ();
  738. X
  739. X#undef P_
  740. X
  741. X#define    MAXDBLINE    256    /* longest allowable database file line */
  742. X#define    FLDSEP        ','    /* major field separator */
  743. X#define    SUBFLD        '|'    /* subfield separator */
  744. X
  745. X#define    ASIZ(a)    (sizeof(a)/sizeof(a[0]))
  746. X
  747. X/* This counter is incremented when we want to mark all the Obj derived entries
  748. X * as being out-of-date. This works because then each of the age's will be !=
  749. X * db_age. This is to eliminate ever calling obj_cir() under the same
  750. X * circumstances for a given db object.
  751. X * N.B. For this to work, call db_update() before using a Obj *.
  752. X */
  753. Xstatic Objage_t db_age;
  754. X
  755. X/* the "database".
  756. X * there is a malloced array of each each type of object.
  757. X * N.B. first NOBJ (see astro.h) objects are kept as a special case.
  758. X * each array has nmem entries, nobj of which are valid; we realloc in groups
  759. X * of DBMEMCHUNKS as a malloc cache.
  760. X */
  761. X#define    DBMEMCHUNKS    200    /* number of things we realloc more at once */
  762. Xstatic char *db[NOBJTYPES];    /* actually arrays of each subtype */
  763. Xstatic int nobj[NOBJTYPES];    /* number of entries in db[type] valid */
  764. Xstatic int nmem[NOBJTYPES];    /* total number of entries in db[type] */
  765. Xstatic Obj basic[NOBJ];        /* special storage for the basic objects */
  766. Xstatic int totnobj;        /* grand total number of objects */
  767. Xstatic int objsize[NOBJTYPES];    /* sizeof each type */
  768. X
  769. X/* return number of objects in the database.
  770. X * N.B. this is expected to be very inexpensive to call.
  771. X */
  772. Xint
  773. Xdb_n()
  774. X{
  775. X    if (!totnobj)
  776. X        db_init();
  777. X    return (totnobj);
  778. X}
  779. X
  780. X/* given one of the basic ids in astro.h return pointer to its Obj in the
  781. X * database.
  782. X */
  783. XObj *
  784. Xdb_basic(id)
  785. Xint id;
  786. X{
  787. X    Obj *op;
  788. X
  789. X    if (!totnobj)
  790. X        db_init();
  791. X
  792. X    if (id < 0 || id >= NOBJ) {
  793. X        printf ("db_basic(): bad id: %d\n", id);
  794. X        exit (1);
  795. X    }
  796. X
  797. X    op = &basic[id];
  798. X    if (op->type != UNDEFOBJ)
  799. X        db_update(op);
  800. X    return (op);
  801. X}
  802. X
  803. X/* the user defined object named by id to op.
  804. X */
  805. Xvoid
  806. Xdb_setuserobj(id, op)
  807. Xint id;    /* OBJX or OBJY */
  808. XObj *op;
  809. X{
  810. X    if (id == OBJX || id == OBJY)
  811. X        basic[id] = *op;
  812. X    else {
  813. X        printf ("db_setuserobj(): bad id: %d\n", id);
  814. X        exit (1);
  815. X    }
  816. X}
  817. X
  818. X/* mark all db objects as old
  819. X */
  820. Xvoid
  821. Xdb_invalidate()
  822. X{
  823. X    if (!totnobj)
  824. X        db_init();
  825. X
  826. X    db_age++;
  827. X}
  828. X
  829. X/* given an Obj * into the the db storage, return the "next" one.
  830. X * the idea is to call this function repeatedly to scan for all objects.
  831. X * if op is NULL, return the "first" one.
  832. X * return NULL if there are no more.
  833. X * the series can be limited as to how the basic (NOBJ) set should be included
  834. X *   by adjusting the how parameter.
  835. X * N.B. nothing should be assumed as to the order these are returned.
  836. X * N.B. the s_ fields are *not* updated -- all db_update() when you need that.
  837. X */
  838. XObj *
  839. Xdb_next (op, how)
  840. XObj *op;
  841. XHowNext how;
  842. X{
  843. X    static char me[] = "db_next()";
  844. X    int i;
  845. X
  846. X    if (!totnobj)
  847. X        db_init();
  848. X
  849. X    switch (how) {
  850. X    case OBJS_JUST_BASIC:
  851. X        if (op == NULL)
  852. X        return (&basic[0]);
  853. X        if (op >= &basic[0] && op < &basic[NOBJ-1])
  854. X        return (&basic[op-basic+1]);
  855. X        if (op == &basic[NOBJ-1])
  856. X        return (NULL);
  857. X        break;
  858. X    case OBJS_ALL:
  859. X        if (op == NULL)
  860. X        return (&basic[0]);
  861. X        if (op >= &basic[0] && op < &basic[NOBJ-1])
  862. X        return (&basic[op-basic+1]);
  863. X        /* continue on to remaining stuff ... */
  864. X    case OBJS_ALLBUT_BASIC:
  865. X        if (op == NULL || op == &basic[NOBJ-1]) {
  866. X        for (i = 0; i < NOBJTYPES; i++)
  867. X            if (nobj[i] > 0)
  868. X            return ((Obj *)db[i]);
  869. X        return (NULL);
  870. X        }
  871. X        for (i = 0; i < NOBJTYPES; i++) {
  872. X        char *cp, *lastp;
  873. X        if (nobj[i] == 0)
  874. X            continue;
  875. X        lastp = db[i] + objsize[i]*(nobj[i]-1);
  876. X        cp = (char *)op;
  877. X        if (cp >= db[i] && cp < lastp)
  878. X            return ((Obj *)(cp + objsize[i]));
  879. X        if (cp == lastp) {
  880. X            while (++i < NOBJTYPES)
  881. X            if (nobj[i] > 0)
  882. X                return ((Obj *)db[i]);
  883. X            return (NULL);
  884. X        }
  885. X        }
  886. X        break;
  887. X    default:
  888. X        printf ("%s: bad how: %d\n", me, how);
  889. X        exit (1);
  890. X    }
  891. X
  892. X    printf ("%s: bad op = 0x%x\n", me, (unsigned) op);
  893. X    exit(1);
  894. X    return (NULL);    /* just for lint */
  895. X}
  896. X    
  897. X
  898. X/* see that all the s_* fields in the given object are up to date.
  899. X * always recompute the user defined objects because we don't know when
  900. X * they might have been changed.
  901. X * N.B. it is ok to call this even if op is not actually in the database
  902. X *   although we guarante an actual update occurs if it't not.
  903. X */
  904. Xvoid
  905. Xdb_update(op)
  906. XObj *op;
  907. X{
  908. X    static char me[] = "db_update()";
  909. X
  910. X    if (!totnobj)
  911. X        db_init();
  912. X
  913. X    if (op->type == UNDEFOBJ) {
  914. X        printf ("%s: called with UNDEFOBJ pointer\n", me);
  915. X        exit (1);
  916. X    } 
  917. X    if (op->type <= 0 || op->type >= NOBJTYPES) {
  918. X        printf ("%s: called with bad pointer\n", me);
  919. X        exit (1);
  920. X    } 
  921. X
  922. X    if (op->o_age != db_age || op == &basic[OBJX] || op == &basic[OBJY]) {
  923. X        if (obj_cir (mm_get_now(), op) < 0) {
  924. X        printf ("%s: bad object\n", me);
  925. X        exit(1);
  926. X        }
  927. X        op->o_age = db_age;
  928. X    }
  929. X}
  930. X
  931. X/* read the given database file into memory.
  932. X * if append is set, add to the existing list, else discard all but the
  933. X * basic NOBJ set first.
  934. X * return 0 if all ok, else -1.
  935. X */
  936. Xdb_read (fp, append)
  937. XFILE *fp;
  938. Xint append;
  939. X{
  940. X    char buf[MAXDBLINE];
  941. X    int nobjsave[NOBJTYPES];
  942. X    int nnew;
  943. X    int i;
  944. X
  945. X    if (!totnobj)
  946. X        db_init();
  947. X
  948. X    if (!append) {
  949. X        /* not appending so discard all existing objects */
  950. X        for (i = 0; i < NOBJTYPES; i++) {
  951. X        if (db[i]) {
  952. X            free (db[i]);
  953. X            db[i] = NULL;
  954. X        }
  955. X        nmem[i] = 0;
  956. X        nobj[i] = 0;
  957. X        }
  958. X        totnobj = NOBJ;
  959. X    }
  960. X
  961. X    /* save the current number of objects in case we have trouble so
  962. X     * we can effectively reset the db back to what it is before.
  963. X     */
  964. X    for (i = 0; i < NOBJTYPES; i++)
  965. X        nobjsave[i] = nobj[i];
  966. X
  967. X    /* read each line from the file and add to the db */
  968. X    for (nnew = 0;
  969. X        nxt_db (buf, sizeof(buf), fp) == 0 && db_crack_line (buf) == 0;
  970. X        nnew++)
  971. X        continue;
  972. X    
  973. X    if (!feof(fp)) {
  974. X        /* couldn't read entire file -- discard everything we've added.
  975. X         * ok to leave the raw memory allocated.
  976. X         */
  977. X        for (i = 0; i < NOBJTYPES; i++)
  978. X        nobj[i] = nobjsave[i];
  979. X        return (-1);
  980. X    }
  981. X
  982. X    totnobj += nnew;
  983. X    return (0);
  984. X}
  985. X
  986. X/* given a text buffer and a field id, and a PREF_DATE_FORMAT,
  987. X *   set the corresponding member in *op.
  988. X * return 0 if ok, else -1.
  989. X */
  990. Xdb_set_field (bp, id, pref, op)
  991. Xchar bp[];
  992. XPrefDateFormat pref;
  993. XObj *op;
  994. X{
  995. X    switch (id) {
  996. X    case O_NAME: {
  997. X        (void) strncpy (op->o_name, bp, sizeof(op->o_name)-1);
  998. X        op->o_name[sizeof(op->o_name)-1] = '\0';
  999. X        break;
  1000. X    }
  1001. X    case F_RA: {
  1002. X        int h, m, s;
  1003. X        double f_ra;
  1004. X        f_dec_sexsign (radhr(op->f_RA), &h, &m, &s);
  1005. X        f_sscansex (bp, &h, &m, &s);
  1006. X        f_ra = op->f_RA;
  1007. X        sex_dec (h, m, s, &f_ra);
  1008. X        op->f_RA = hrrad(f_ra);
  1009. X        break;
  1010. X    }
  1011. X    case F_DEC: {
  1012. X        int dg, m, s;
  1013. X        double tdec;
  1014. X        f_dec_sexsign (raddeg(op->f_dec), &dg, &m, &s);
  1015. X        f_sscansex (bp, &dg, &m, &s);
  1016. X        tdec = op->f_dec;
  1017. X        sex_dec (dg, m, s, &tdec);
  1018. X        op->f_dec = degrad(tdec);
  1019. X        break;
  1020. X    }
  1021. X    case F_MAG:
  1022. X        op->f_mag = atof (bp) * MAGSCALE;
  1023. X        break;
  1024. X    case F_SIZE:
  1025. X        op->f_size = atof (bp);
  1026. X        break;
  1027. X    case F_EPOCH: {
  1028. X        double fepoch;
  1029. X        fepoch = op->f_epoch;
  1030. X        crack_year (bp, pref, &fepoch);
  1031. X        op->f_epoch = fepoch;
  1032. X        break;
  1033. X    }
  1034. X    case F_CLASS:
  1035. X        switch (bp[0]) {
  1036. X        case 'C': case 'U': case 'O': case 'G': case 'H': case 'A':
  1037. X        case 'N': case 'F': case 'K': case 'P': case 'Q': case 'T':
  1038. X        case 'B': case 'D': case 'M': case 'S': case 'V':
  1039. X        op->f_class = bp[0];
  1040. X        break;
  1041. X        default:
  1042. X        return (-1);
  1043. X        }
  1044. X        break;
  1045. X    case F_SPECT: {
  1046. X        int i, j;
  1047. X        /* fill f_spect all the way */
  1048. X        for (i = j = 0; i < sizeof(op->f_spect); i++)
  1049. X        if ((op->f_spect[i] = bp[j]) != 0)
  1050. X            j++;
  1051. X        break;
  1052. X    }
  1053. X
  1054. X    case E_INC:
  1055. X        op->e_inc = atof (bp);
  1056. X        break;
  1057. X    case E_LAN:
  1058. X        op->e_Om = atof (bp);
  1059. X        break;
  1060. X    case E_AOP:
  1061. X        op->e_om = atof (bp);
  1062. X        break;
  1063. X    case E_A:
  1064. X        op->e_a = atof (bp);
  1065. X        break;
  1066. X    case E_N:
  1067. X        op->e_n = atof (bp);
  1068. X        break;
  1069. X    case E_E:
  1070. X        op->e_e = atof (bp);
  1071. X        break;
  1072. X    case E_M:
  1073. X        op->e_M = atof (bp);
  1074. X        break;
  1075. X    case E_CEPOCH:
  1076. X        crack_year (bp, pref, &op->e_cepoch);
  1077. X        break;
  1078. X    case E_EPOCH:
  1079. X        crack_year (bp, pref, &op->e_epoch);
  1080. X        break;
  1081. X    case E_M1:
  1082. X        switch (bp[0]) {
  1083. X        case 'g':
  1084. X        op->e_mag.whichm = MAG_gk;
  1085. X        bp++;
  1086. X        break;
  1087. X        case 'H':
  1088. X        op->e_mag.whichm = MAG_HG;
  1089. X        bp++;
  1090. X        break;
  1091. X        default:
  1092. X        /* leave type unchanged if no or unrecognized prefix */
  1093. X        break;
  1094. X        }
  1095. X        op->e_mag.m1 = atof(bp);
  1096. X        break;
  1097. X    case E_M2:
  1098. X        switch (bp[0]) {
  1099. X        case 'k':
  1100. X        op->e_mag.whichm = MAG_gk;
  1101. X        bp++;
  1102. X        break;
  1103. X        case 'G':
  1104. X        op->e_mag.whichm = MAG_HG;
  1105. X        bp++;
  1106. X        break;
  1107. X        default:
  1108. X        /* leave type unchanged if no or unrecognized prefix */
  1109. X        break;
  1110. X        }
  1111. X        op->e_mag.m2 = atof(bp);
  1112. X        break;
  1113. X    case E_SIZE:
  1114. X        op->e_size = atof (bp);
  1115. X        break;
  1116. X
  1117. X    case H_EP:
  1118. X        crack_year (bp, pref, &op->h_ep);
  1119. X        break;
  1120. X    case H_INC:
  1121. X        op->h_inc = atof (bp);
  1122. X        break;
  1123. X    case H_LAN:
  1124. X        op->h_Om = atof (bp);
  1125. X        break;
  1126. X    case H_AOP:
  1127. X        op->h_om = atof (bp);
  1128. X        break;
  1129. X    case H_E:
  1130. X        op->h_e = atof (bp);
  1131. X        break;
  1132. X    case H_QP:
  1133. X        op->h_qp = atof (bp);
  1134. X        break;
  1135. X    case H_EPOCH:
  1136. X        crack_year (bp, pref, &op->h_epoch);
  1137. X        break;
  1138. X    case H_G:
  1139. X        op->h_g = atof (bp);
  1140. X        break;
  1141. X    case H_K:
  1142. X        op->h_k = atof (bp);
  1143. X        break;
  1144. X    case H_SIZE:
  1145. X        op->h_size = atof (bp);
  1146. X        break;
  1147. X
  1148. X    case P_EP:
  1149. X        crack_year (bp, pref, &op->p_ep);
  1150. X        break;
  1151. X    case P_INC:
  1152. X        op->p_inc = atof (bp);
  1153. X        break;
  1154. X    case P_AOP:
  1155. X        op->p_om = atof (bp);
  1156. X        break;
  1157. X    case P_QP:
  1158. X        op->p_qp = atof (bp);
  1159. X        break;
  1160. X    case P_LAN:
  1161. X        op->p_Om = atof (bp);
  1162. X        break;
  1163. X    case P_EPOCH:
  1164. X        crack_year (bp, pref, &op->p_epoch);
  1165. X        break;
  1166. X    case P_G:
  1167. X        op->p_g = atof (bp);
  1168. X        break;
  1169. X    case P_K:
  1170. X        op->p_k = atof (bp);
  1171. X        break;
  1172. X    case P_SIZE:
  1173. X        op->p_size = atof (bp);
  1174. X        break;
  1175. X    default:
  1176. X        printf ("BUG! db_set_field: bad id: %d\n", id);
  1177. X        exit (1);
  1178. X    }
  1179. X
  1180. X    return (0);
  1181. X}
  1182. X
  1183. X/* allocate and return zero'd room for a new object with the given type.
  1184. X * N.B we do *not* validate t.
  1185. X * reurn NULL if can't get more room.
  1186. X */
  1187. Xstatic Obj *
  1188. Xdb_new (t)
  1189. Xint t;
  1190. X{
  1191. X    int size = objsize[t];
  1192. X    int newidx;
  1193. X
  1194. X    /* allocate more room if this type can't hold another one */
  1195. X    if (nobj[t] >= nmem[t]) {
  1196. X        int oldn = nmem[t];
  1197. X        int newn = oldn + DBMEMCHUNKS;
  1198. X        char *newp = db[t] ? realloc (db[t], size*newn)
  1199. X                   : malloc (size*newn);
  1200. X        if (!newp)
  1201. X        return (NULL);
  1202. X        zero_mem (newp + size*oldn, size*DBMEMCHUNKS);
  1203. X        nmem[t] = newn;
  1204. X        db[t] = newp;
  1205. X    }
  1206. X
  1207. X    /* the next index to use is the current number of entries */
  1208. X    newidx = nobj[t]++;
  1209. X
  1210. X    /* find the address of the new entry */
  1211. X    return ((Obj *)(db[t] + size*newidx));
  1212. X}
  1213. X
  1214. X/* crack the given database line and add to corresponding db list.
  1215. X * return 0 if ok else put up a message and return -1.
  1216. X */
  1217. Xstatic
  1218. Xdb_crack_line (s)
  1219. Xchar *s;
  1220. X{
  1221. X    static char nomem[] = "Insufficient memory to load this database\n";
  1222. X#define    MAXFLDS    20        /* must be more than on any expected line */
  1223. X    char *flds[MAXFLDS];    /* point to each field for easy reference */
  1224. X    char *sflds[MAXFLDS];    /* point to each sub field for easy reference */
  1225. X    char copy[MAXDBLINE];    /* work copy; leave s untouched */
  1226. X    char msg[512];        /* misc message buffer */
  1227. X    int nf, nsf;        /* number of fields and subfields */
  1228. X    Obj *op;
  1229. X    int i;
  1230. X
  1231. X    /* do all the parsing on a copy */
  1232. X    (void) strcpy (copy, s);
  1233. X
  1234. X    /* parse into main fields */
  1235. X    nf = get_fields (copy, FLDSEP, flds);
  1236. X
  1237. X    /* need at least 2: name and type */
  1238. X    if (nf < 2) {
  1239. X        (void)sprintf(msg, "Too few fields in Database line: `%.480s'\n",s);
  1240. X        xe_msg (msg, 0);
  1241. X        return (-1);
  1242. X    }
  1243. X
  1244. X    /* switch out on type of object - the second field */
  1245. X    switch (flds[1][0]) {
  1246. X    case 'f': {
  1247. X        static int ids[] = {F_RA, F_DEC, F_MAG, F_EPOCH};
  1248. X        if (nf != 6 && nf != 7) {
  1249. X        (void)sprintf(msg,
  1250. X            "Need ra,dec,mag,[epoch][,siz] for fixed object `%.460s'\n",
  1251. X                                    flds[0]);
  1252. X        xe_msg (msg, 0);
  1253. X        return (-1);
  1254. X        }
  1255. X        op = db_new(FIXED);
  1256. X        if (!op) {
  1257. X        xe_msg (nomem, 1);
  1258. X        return (-1);
  1259. X        }
  1260. X        op->type = FIXED;
  1261. X        nsf = get_fields(flds[1], SUBFLD, sflds);
  1262. X        if (nsf > 1 && db_set_field (sflds[1], F_CLASS, PREF_MDY, op) < 0) {
  1263. X        (void) sprintf(msg,"Bad class `%c' for fixed object `%.450s'\n",
  1264. X                                *sflds[1], flds[0]);
  1265. X        xe_msg (msg, 0);
  1266. X        return (-1);
  1267. X        }
  1268. X        if (nsf > 2)
  1269. X        (void) db_set_field (sflds[2], F_SPECT, PREF_MDY, op);
  1270. X        for (i = 2; i < ASIZ(ids)+2; i++)
  1271. X        (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
  1272. X        if (nf == 7)
  1273. X        (void) db_set_field (flds[6], F_SIZE, PREF_MDY, op);
  1274. X        break;
  1275. X    }
  1276. X
  1277. X    case 'e': {
  1278. X        static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
  1279. X                        E_CEPOCH, E_EPOCH, E_M1, E_M2
  1280. X        };
  1281. X        if (nf != 13 && nf != 14) {
  1282. X        (void)sprintf (msg,
  1283. X            "Need i,O,o,a,n,e,M,E,D,H/g,G/k[,siz] for elliptical object `%.450s'\n",
  1284. X                                    flds[0]);
  1285. X        xe_msg(msg, 0);
  1286. X        return (-1);
  1287. X        }
  1288. X        op = db_new(ELLIPTICAL);
  1289. X        if (!op) {
  1290. X        xe_msg (nomem, 1);
  1291. X        return (-1);
  1292. X        }
  1293. X        op->type = ELLIPTICAL;
  1294. X        for (i = 2; i < ASIZ(ids)+2; i++)
  1295. X        (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
  1296. X        if (nf == 14)
  1297. X        (void) db_set_field (flds[13], E_SIZE, PREF_MDY, op);
  1298. X        break;
  1299. X    }
  1300. X
  1301. X    case 'h': {
  1302. X        static int ids[]= {H_EP,H_INC,H_LAN,H_AOP,H_E,H_QP,H_EPOCH,H_G,H_K};
  1303. X        if (nf != 11 && nf != 12) {
  1304. X        (void)sprintf (msg,
  1305. X            "Need T,i,O,o,e,q,D,g,k[,siz] for hyperbolic object `%.450s'\n",
  1306. X                                    flds[0]);
  1307. X        xe_msg(msg, 0);
  1308. X        return (-1);
  1309. X        }
  1310. X        op = db_new(HYPERBOLIC);
  1311. X        if (!op) {
  1312. X        xe_msg (nomem, 1);
  1313. X        return (-1);
  1314. X        }
  1315. X        op->type = HYPERBOLIC;
  1316. X        for (i = 2; i < ASIZ(ids)+2; i++)
  1317. X        (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
  1318. X        if (nf == 12)
  1319. X        (void) db_set_field (flds[11], H_SIZE, PREF_MDY, op);
  1320. X        break;
  1321. X    }
  1322. X
  1323. X    case 'p': {
  1324. X        static int ids[] = {P_EP,P_INC,P_AOP,P_QP,P_LAN,P_EPOCH,P_G,P_K};
  1325. X        if (nf != 10 && nf != 11) {
  1326. X        (void)sprintf (msg,
  1327. X            "Need T,i,o,q,O,D,g,k[,siz] for parabolic object `%.450s'\n",
  1328. X                                    flds[0]);
  1329. X        xe_msg(msg, 0);
  1330. X        return (-1);
  1331. X        }
  1332. X        op = db_new(PARABOLIC);
  1333. X        if (!op) {
  1334. X        xe_msg (nomem, 1);
  1335. X        return (-1);
  1336. X        }
  1337. X        op->type = PARABOLIC;
  1338. X        for (i = 2; i < ASIZ(ids)+2; i++)
  1339. X        (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
  1340. X        if (nf == 11)
  1341. X        (void) db_set_field (flds[10], P_SIZE, PREF_MDY, op);
  1342. X        break;
  1343. X    }
  1344. X
  1345. X    default:
  1346. X        (void)sprintf (msg,
  1347. X        "Unknown type for Object %s: `%.480s'\n", flds[0], flds[1]);
  1348. X        xe_msg(msg, 0);
  1349. X        return (-1);
  1350. X    }
  1351. X
  1352. X    /* load up name */
  1353. X    (void) db_set_field (flds[0], O_NAME, PREF_MDY, op);
  1354. X
  1355. X    return (0);
  1356. X}
  1357. X
  1358. X/* set up the basic database.
  1359. X */
  1360. Xstatic void
  1361. Xdb_init()
  1362. X{
  1363. X    /* these must match the order in astro.h */
  1364. X    static char *planet_names[] = {
  1365. X        "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
  1366. X        "Uranus", "Neptune", "Pluto", "Sun", "Moon",
  1367. X    };
  1368. X
  1369. X    int i;
  1370. X
  1371. X    /* init the planets */
  1372. X    for (i = MERCURY; i <= MOON; i++) {
  1373. X        Obj *op = &basic[i];
  1374. X        op->type = PLANET;
  1375. X        (void) strncpy (op->o_name, planet_names[i], sizeof(op->o_name)-1);
  1376. X        op->pl.code = i;
  1377. X    }
  1378. X
  1379. X    /* the total includes the planets and the 2 undefined user objs too */
  1380. X    totnobj = NOBJ;
  1381. X
  1382. X    /* init the object size array */
  1383. X    objsize[UNDEFOBJ] =    0;
  1384. X    objsize[FIXED] =    sizeof(ObjF);
  1385. X    objsize[ELLIPTICAL] =    sizeof(ObjE);
  1386. X    objsize[HYPERBOLIC] =    sizeof(ObjH);
  1387. X    objsize[PARABOLIC] =    sizeof(ObjP);
  1388. X    objsize[PLANET] =    sizeof(ObjPl);
  1389. X}
  1390. X
  1391. X/* read database file fp and put next valid entry (sans trailing \n) into buf.
  1392. X * we only count those lines that begin with alpha or numeric chars.
  1393. X * return 0 if ok.
  1394. X * if eof: return -1; caller will find that feof(fp) is true;
  1395. X * other errors: print a message and return -1.
  1396. X */
  1397. Xstatic int
  1398. Xnxt_db (buf, blen, fp)
  1399. Xchar buf[];
  1400. Xint blen;
  1401. XFILE *fp;
  1402. X{
  1403. X    char c;
  1404. X    int l;
  1405. X
  1406. X    for (;;) {
  1407. X        if (fgets (buf, blen, fp) == 0)
  1408. X        return (-1);
  1409. X        l = strlen(buf);
  1410. X        if (buf[l-1] != '\n') {
  1411. X        xe_msg ("Databse file line length is too long\n", 1);
  1412. X        return (-1);
  1413. X        }
  1414. X        c = buf[0];
  1415. X        if (isalpha(c) || isdigit(c)) {
  1416. X        buf[l-1] = '\0';
  1417. X        return (0);
  1418. X        }
  1419. X    }
  1420. X}
  1421. X
  1422. X/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x)
  1423. X * and a DateFormat preference convert it to an mjd and store it at *p.
  1424. X */
  1425. Xstatic void
  1426. Xcrack_year (bp, pref, p)
  1427. Xchar *bp;
  1428. XPrefDateFormat pref;
  1429. Xdouble *p;
  1430. X{
  1431. X    int m, y;
  1432. X    double d;
  1433. X
  1434. X    mjd_cal (*p, &m, &d, &y);    /* init with current */
  1435. X    f_sscandate (bp, pref, &m, &d, &y);
  1436. X    cal_mjd (m, d, y, p);
  1437. X}
  1438. X
  1439. X/* given a null-terminated string, fill in fields[] with the starting addresses
  1440. X * of each field delimited by delim or '\0'.
  1441. X * N.B. each character matching delim is REPLACED BY '\0' IN PLACE.
  1442. X * N.B. 0-length fields count, so even if *s=='\0' we return 1.
  1443. X * return the number of fields.
  1444. X */
  1445. Xstatic
  1446. Xget_fields (s, delim, fields)
  1447. Xchar *s;
  1448. Xchar delim;
  1449. Xchar *fields[];
  1450. X{
  1451. X    int n;
  1452. X    char c;
  1453. X
  1454. X    *fields = s;
  1455. X    n = 0;
  1456. X    do {
  1457. X        c = *s++;
  1458. X        if (c == delim || c == '\0') {
  1459. X        s[-1] = '\0';
  1460. X        *++fields = s;
  1461. X        n++;
  1462. X        }
  1463. X    } while (c);
  1464. X
  1465. X    return (n);
  1466. X}
  1467. END_OF_FILE
  1468.   if test 18368 -ne `wc -c <'db.c'`; then
  1469.     echo shar: \"'db.c'\" unpacked with wrong size!
  1470.   fi
  1471.   # end of 'db.c'
  1472. fi
  1473. if test -f 'plans.c' -a "${1}" != "-c" ; then 
  1474.   echo shar: Will not clobber existing file \"'plans.c'\"
  1475. else
  1476.   echo shar: Extracting \"'plans.c'\" \(19091 characters\)
  1477.   sed "s/^X//" >'plans.c' <<'END_OF_FILE'
  1478. X#include <stdio.h>
  1479. X#include <math.h>
  1480. X#include "astro.h"
  1481. X
  1482. X
  1483. X#if defined(__STDC__) || defined(__cplusplus)
  1484. X#define P_(s) s
  1485. X#else
  1486. X#define P_(s) ()
  1487. X#endif
  1488. X
  1489. Xextern void anomaly P_((double ma, double s, double *nu, double *ea));
  1490. Xextern void pelement P_((double Mjd, double plan[8][9]));
  1491. Xextern void range P_((double *v, double r));
  1492. Xextern void sunpos P_((double Mjd, double *lsn, double *rsn));
  1493. X
  1494. Xvoid plans P_((double mjd, int p, double *lpd0, double *psi0, double *rp0, double *rho0, double *lam, double *bet, double *dia, double *mag));
  1495. Xstatic void aux_jsun P_((double t, double *x1, double *x2, double *x3, double *x4, double *x5, double *x6));
  1496. Xstatic void masun P_((double mjd, double *mas));
  1497. Xstatic void p_mercury P_((double map[], double *dl, double *dr));
  1498. Xstatic void p_venus P_((double t, double mas, double map[], double *dl, double *dr, double *dml, double *dm));
  1499. Xstatic void p_mars P_((double mas, double map[], double *dl, double *dr, double *dml, double *dm));
  1500. Xstatic void p_jupiter P_((double t, double s, double *dml, double *ds, double *dm, double *da));
  1501. Xstatic void p_saturn P_((double t, double s, double *dml, double *ds, double *dm, double *da, double *dhl));
  1502. Xstatic void p_uranus P_((double t, double s, double *dl, double *dr, double *dml, double *ds, double *dm, double *da, double *dhl));
  1503. Xstatic void p_neptune P_((double t, double s, double *dl, double *dr, double *dml, double *ds, double *dm, double *da, double *dhl));
  1504. X
  1505. X#undef P_
  1506. X
  1507. X#define    TWOPI        (2*PI)
  1508. X#define    mod2PI(x)    ((x) - (long)((x)/TWOPI)*TWOPI)
  1509. X
  1510. X/* given a modified Julian date, mjd, and a planet, p, find:
  1511. X *   lpd0: heliocentric longitude, 
  1512. X *   psi0: heliocentric latitude,
  1513. X *   rp0:  distance from the sun to the planet, 
  1514. X *   rho0: distance from the Earth to the planet,
  1515. X *         none corrected for light time, ie, they are the true values for the
  1516. X *         given instant.
  1517. X *   lam:  geocentric ecliptic longitude, 
  1518. X *   bet:  geocentric ecliptic latitude,
  1519. X *         each corrected for light time, ie, they are the apparent values as
  1520. X *       seen from the center of the Earth for the given instant.
  1521. X *   dia:  angular diameter in arcsec at 1 AU, 
  1522. X *   mag:  visual magnitude when 1 AU from sun and earth at 0 phase angle.
  1523. X *
  1524. X * all angles are in radians, all distances in AU.
  1525. X * the mean orbital elements are found by calling pelement(), then mutual
  1526. X *   perturbation corrections are applied as necessary.
  1527. X *
  1528. X * corrections for nutation and abberation must be made by the caller. The RA 
  1529. X *   and DEC calculated from the fully-corrected ecliptic coordinates are then
  1530. X *   the apparent geocentric coordinates. Further corrections can be made, if
  1531. X *   required, for atmospheric refraction and geocentric parallax although the
  1532. X *   intrinsic error herein of about 10 arcseconds is usually the dominant
  1533. X *   error at this stage.
  1534. X * TODO: combine the several intermediate expressions when get a good compiler.
  1535. X */
  1536. Xvoid
  1537. Xplans (mjd, p, lpd0, psi0, rp0, rho0, lam, bet, dia, mag)
  1538. Xdouble mjd;
  1539. Xint p;
  1540. Xdouble *lpd0, *psi0, *rp0, *rho0, *lam, *bet, *dia, *mag;
  1541. X{
  1542. X    static double plan[8][9];
  1543. X    static double lastmjd = -10000;
  1544. X    double dl;    /* perturbation correction for longitude */
  1545. X    double dr;    /*  "   orbital radius */
  1546. X    double dml;    /*  "   mean longitude */
  1547. X    double ds;    /*  "   eccentricity */
  1548. X    double dm;    /*  "   mean anomaly */
  1549. X    double da;    /*  "   semi-major axis */
  1550. X    double dhl;    /*  "   heliocentric longitude */
  1551. X    double lsn, rsn;/* true geocentric longitude of sun and sun-earth rad */
  1552. X    double mas;    /* mean anomaly of the sun */
  1553. X    double re;    /* radius of earth's orbit */
  1554. X    double lg;    /* longitude of earth */
  1555. X    double map[8];    /* array of mean anomalies for each planet */
  1556. X    double lpd, psi, rp, rho;
  1557. X    double ll, sll, cll;
  1558. X    double t;
  1559. X    double dt;
  1560. X    int pass;
  1561. X    int j;
  1562. X    double s, ma;
  1563. X    double nu, ea;
  1564. X    double lp, om;
  1565. X    double lo, slo, clo;
  1566. X    double inc, y;
  1567. X    double spsi, cpsi;
  1568. X    double rpd;
  1569. X
  1570. X    /* only need to fill in plan[] once for a given mjd */
  1571. X    if (mjd != lastmjd) {
  1572. X        pelement (mjd, plan);
  1573. X        lastmjd = mjd;
  1574. X    }
  1575. X
  1576. X    dt = 0;
  1577. X    t = mjd/36525.;
  1578. X    sunpos (mjd, &lsn, &rsn);
  1579. X    masun (mjd, &mas);
  1580. X        re = rsn;
  1581. X    lg = lsn+PI;
  1582. X
  1583. X    /* first find the true position of the planet at mjd.
  1584. X     * then repeat a second time for a slightly different time based
  1585. X     * on the position found in the first pass to account for light-travel
  1586. X     * time.
  1587. X     */
  1588. X    for (pass = 0; pass < 2; pass++) {
  1589. X
  1590. X        for (j = 0; j < 8; j++)
  1591. X        map[j] = degrad(plan[j][0]-plan[j][2]-dt*plan[j][1]);
  1592. X
  1593. X        /* set initial corrections to 0.
  1594. X         * then modify as necessary for the planet of interest.
  1595. X         */
  1596. X        dl = 0;
  1597. X        dr = 0;
  1598. X        dml = 0;
  1599. X        ds = 0;
  1600. X        dm = 0;
  1601. X        da = 0;
  1602. X        dhl = 0;
  1603. X
  1604. X        switch (p) {
  1605. X
  1606. X        case MERCURY:
  1607. X        p_mercury (map, &dl, &dr);
  1608. X        break;
  1609. X
  1610. X        case VENUS:
  1611. X        p_venus (t, mas, map, &dl, &dr, &dml, &dm);
  1612. X        break;
  1613. X
  1614. X        case MARS:
  1615. X        p_mars (mas, map, &dl, &dr, &dml, &dm);
  1616. X        break;
  1617. X
  1618. X        case JUPITER:
  1619. X        p_jupiter (t, plan[p][3], &dml, &ds, &dm, &da);
  1620. X        break;
  1621. X
  1622. X        case SATURN:
  1623. X        p_saturn (t, plan[p][3], &dml, &ds, &dm, &da, &dhl);
  1624. X        break;
  1625. X
  1626. X        case URANUS:
  1627. X        p_uranus (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
  1628. X        break;
  1629. X
  1630. X        case NEPTUNE:
  1631. X        p_neptune (t, plan[p][3], &dl, &dr, &dml, &ds, &dm, &da, &dhl);
  1632. X        break;
  1633. X
  1634. X        case PLUTO:
  1635. X        /* no perturbation theory for pluto */
  1636. X        break;
  1637. X        }
  1638. X
  1639. X        s = plan[p][3]+ds;
  1640. X        ma = map[p]+dm;
  1641. X        anomaly (ma, s, &nu, &ea);
  1642. X        rp = (plan[p][6]+da)*(1-s*s)/(1+s*cos(nu));
  1643. X        lp = raddeg(nu)+plan[p][2]+raddeg(dml-dm);
  1644. X        lp = degrad(lp);
  1645. X        om = degrad(plan[p][5]);
  1646. X        lo = lp-om;
  1647. X        slo = sin(lo);
  1648. X        clo = cos(lo);
  1649. X        inc = degrad(plan[p][4]);
  1650. X        rp = rp+dr;
  1651. X        spsi = slo*sin(inc);
  1652. X        y = slo*cos(inc);
  1653. X        psi = asin(spsi)+dhl;
  1654. X        spsi = sin(psi);
  1655. X        lpd = atan(y/clo)+om+degrad(dl);
  1656. X        if (clo<0) lpd += PI;
  1657. X        range (&lpd, TWOPI);
  1658. X        cpsi = cos(psi);
  1659. X        rpd = rp*cpsi;
  1660. X        ll = lpd-lg;
  1661. X        rho = sqrt(re*re+rp*rp-2*re*rp*cpsi*cos(ll));
  1662. X
  1663. X        /* when we view a planet we see it in the position it occupied
  1664. X         * dt days ago, where rho is the distance between it and earth,
  1665. X         * in AU. use this as the new time for the next pass.
  1666. X         */
  1667. X        dt = rho*5.775518e-3;
  1668. X
  1669. X        if (pass == 0) {
  1670. X        /* save heliocentric coordinates after first pass since, being
  1671. X         * true, they are NOT to be corrected for light-travel time.
  1672. X         */
  1673. X        *lpd0 = lpd;
  1674. X        range (lpd0, TWOPI);
  1675. X        *psi0 = psi;
  1676. X        *rp0 = rp;
  1677. X        *rho0 = rho;
  1678. X        }
  1679. X    }
  1680. X
  1681. X        sll = sin(ll);
  1682. X    cll = cos(ll);
  1683. X        if (p < MARS) 
  1684. X        *lam = atan(-1*rpd*sll/(re-rpd*cll))+lg+PI;
  1685. X    else
  1686. X        *lam = atan(re*sll/(rpd-re*cll))+lpd;
  1687. X    range (lam, TWOPI);
  1688. X        *bet = atan(rpd*spsi*sin(*lam-lpd)/(cpsi*re*sll));
  1689. X    *dia = plan[p][7];
  1690. X    *mag = plan[p][8];
  1691. X}
  1692. X
  1693. X/* set auxilliary variables used for jupiter, saturn, uranus, and neptune */
  1694. Xstatic void
  1695. Xaux_jsun (t, x1, x2, x3, x4, x5, x6)
  1696. Xdouble t;
  1697. Xdouble *x1, *x2, *x3, *x4, *x5, *x6;
  1698. X{
  1699. X        *x1 = t/5+0.1;
  1700. X        *x2 = mod2PI(4.14473+5.29691e1*t);
  1701. X        *x3 = mod2PI(4.641118+2.132991e1*t);
  1702. X        *x4 = mod2PI(4.250177+7.478172*t);
  1703. X        *x5 = 5 * *x3 - 2 * *x2;
  1704. X    *x6 = 2 * *x2 - 6 * *x3 + 3 * *x4;
  1705. X}
  1706. X
  1707. X/* find the mean anomaly of the sun at mjd.
  1708. X * this is the same as that used in sun() but when it was converted to C it
  1709. X * was not known it would be required outside that routine.
  1710. X * TODO: add an argument to sun() to return mas and eliminate this routine.
  1711. X */
  1712. Xstatic void
  1713. Xmasun (mjd, mas)
  1714. Xdouble mjd;
  1715. Xdouble *mas;
  1716. X{
  1717. X    double t, t2;
  1718. X    double a, b;
  1719. X
  1720. X    t = mjd/36525;
  1721. X    t2 = t*t;
  1722. X    a = 9.999736042e1*t;
  1723. X    b = 360.*(a-(long)a);
  1724. X    *mas = degrad (3.5847583e2-(1.5e-4+3.3e-6*t)*t2+b);
  1725. X}
  1726. X
  1727. X/* perturbations for mercury */
  1728. Xstatic void
  1729. Xp_mercury (map, dl, dr)
  1730. Xdouble map[];
  1731. Xdouble *dl, *dr;
  1732. X{
  1733. X    *dl = 2.04e-3*cos(5*map[2-1]-2*map[1-1]+2.1328e-1)+
  1734. X         1.03e-3*cos(2*map[2-1]-map[1-1]-2.8046)+
  1735. X         9.1e-4*cos(2*map[3]-map[1-1]-6.4582e-1)+
  1736. X         7.8e-4*cos(5*map[2-1]-3*map[1-1]+1.7692e-1);
  1737. X
  1738. X    *dr = 7.525e-6*cos(2*map[3]-map[1-1]+9.25251e-1)+
  1739. X         6.802e-6*cos(5*map[2-1]-3*map[1-1]-4.53642)+
  1740. X         5.457e-6*cos(2*map[2-1]-2*map[1-1]-1.24246)+
  1741. X         3.569e-6*cos(5*map[2-1]-map[1-1]-1.35699);
  1742. X}
  1743. X
  1744. X/* ....venus */
  1745. Xstatic void
  1746. Xp_venus (t, mas, map, dl, dr, dml, dm)
  1747. Xdouble t, mas, map[];
  1748. Xdouble *dl, *dr, *dml, *dm;
  1749. X{
  1750. X    *dml = degrad (7.7e-4*sin(4.1406+t*2.6227));
  1751. X    *dm = *dml;
  1752. X
  1753. X    *dl = 3.13e-3*cos(2*mas-2*map[2-1]-2.587)+
  1754. X         1.98e-3*cos(3*mas-3*map[2-1]+4.4768e-2)+
  1755. X         1.36e-3*cos(mas-map[2-1]-2.0788)+
  1756. X         9.6e-4*cos(3*mas-2*map[2-1]-2.3721)+
  1757. X         8.2e-4*cos(map[3]-map[2-1]-3.6318);
  1758. X
  1759. X    *dr = 2.2501e-5*cos(2*mas-2*map[2-1]-1.01592)+
  1760. X         1.9045e-5*cos(3*mas-3*map[2-1]+1.61577)+
  1761. X         6.887e-6*cos(map[3]-map[2-1]-2.06106)+
  1762. X         5.172e-6*cos(mas-map[2-1]-5.08065e-1)+
  1763. X         3.62e-6*cos(5*mas-4*map[2-1]-1.81877)+
  1764. X         3.283e-6*cos(4*mas-4*map[2-1]+1.10851)+
  1765. X         3.074e-6*cos(2*map[3]-2*map[2-1]-9.62846e-1);
  1766. X}
  1767. X
  1768. X/* ....mars */
  1769. Xstatic void
  1770. Xp_mars (mas, map, dl, dr, dml, dm)
  1771. Xdouble mas, map[];
  1772. Xdouble *dl, *dr, *dml, *dm;
  1773. X{
  1774. X    double a;
  1775. X
  1776. X    a = 3*map[3]-8*map[2]+4*mas;
  1777. X    *dml = degrad (-1*(1.133e-2*sin(a)+9.33e-3*cos(a)));
  1778. X    *dm = *dml;
  1779. X
  1780. X    *dl = 7.05e-3*cos(map[3]-map[2]-8.5448e-1)+
  1781. X         6.07e-3*cos(2*map[3]-map[2]-3.2873)+
  1782. X         4.45e-3*cos(2*map[3]-2*map[2]-3.3492)+
  1783. X         3.88e-3*cos(mas-2*map[2]+3.5771e-1)+
  1784. X         2.38e-3*cos(mas-map[2]+6.1256e-1)+
  1785. X         2.04e-3*cos(2*mas-3*map[2]+2.7688)+
  1786. X         1.77e-3*cos(3*map[2]-map[2-1]-1.0053)+
  1787. X         1.36e-3*cos(2*mas-4*map[2]+2.6894)+
  1788. X         1.04e-3*cos(map[3]+3.0749e-1);
  1789. X
  1790. X    *dr = 5.3227e-5*cos(map[3]-map[2]+7.17864e-1)+
  1791. X         5.0989e-5*cos(2*map[3]-2*map[2]-1.77997)+
  1792. X         3.8278e-5*cos(2*map[3]-map[2]-1.71617)+
  1793. X         1.5996e-5*cos(mas-map[2]-9.69618e-1)+
  1794. X         1.4764e-5*cos(2*mas-3*map[2]+1.19768)+
  1795. X         8.966e-6*cos(map[3]-2*map[2]+7.61225e-1);
  1796. X     *dr += 7.914e-6*cos(3*map[3]-2*map[2]-2.43887)+
  1797. X         7.004e-6*cos(2*map[3]-3*map[2]-1.79573)+
  1798. X         6.62e-6*cos(mas-2*map[2]+1.97575)+
  1799. X         4.93e-6*cos(3*map[3]-3*map[2]-1.33069)+
  1800. X         4.693e-6*cos(3*mas-5*map[2]+3.32665)+
  1801. X         4.571e-6*cos(2*mas-4*map[2]+4.27086)+
  1802. X         4.409e-6*cos(3*map[3]-map[2]-2.02158);
  1803. X}
  1804. X
  1805. X/* ....jupiter */
  1806. Xstatic void
  1807. Xp_jupiter (t, s, dml, ds, dm, da)
  1808. Xdouble t, s;
  1809. Xdouble *dml, *ds, *dm, *da;
  1810. X{
  1811. X    double dp;
  1812. X    double x1, x2, x3, x4, x5, x6, x7;
  1813. X    double sx3, cx3, s2x3, c2x3;
  1814. X        double sx5, cx5, s2x5;
  1815. X    double sx6;
  1816. X        double sx7, cx7, s2x7, c2x7, s3x7, c3x7, s4x7, c4x7, c5x7;
  1817. X
  1818. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  1819. X        x7 = x3-x2;
  1820. X    sx3 = sin(x3);
  1821. X    cx3 = cos(x3);
  1822. X        s2x3 = sin(2*x3);
  1823. X    c2x3 = cos(2*x3);
  1824. X        sx5 = sin(x5);
  1825. X    cx5 = cos(x5);
  1826. X        s2x5 = sin(2*x5);
  1827. X    sx6 = sin(x6);
  1828. X        sx7 = sin(x7);
  1829. X    cx7 = cos(x7);
  1830. X        s2x7 = sin(2*x7);
  1831. X    c2x7 = cos(2*x7);
  1832. X        s3x7 = sin(3*x7);
  1833. X    c3x7 = cos(3*x7);
  1834. X        s4x7 = sin(4*x7);
  1835. X    c4x7 = cos(4*x7);
  1836. X        c5x7 = cos(5*x7);
  1837. X
  1838. X    *dml = (3.31364e-1-(1.0281e-2+4.692e-3*x1)*x1)*sx5+
  1839. X          (3.228e-3-(6.4436e-2-2.075e-3*x1)*x1)*cx5-
  1840. X          (3.083e-3+(2.75e-4-4.89e-4*x1)*x1)*s2x5+
  1841. X          2.472e-3*sx6+1.3619e-2*sx7+1.8472e-2*s2x7+6.717e-3*s3x7+
  1842. X          2.775e-3*s4x7+6.417e-3*s2x7*sx3+
  1843. X          (7.275e-3-1.253e-3*x1)*sx7*sx3+
  1844. X          2.439e-3*s3x7*sx3-(3.5681e-2+1.208e-3*x1)*sx7*cx3;
  1845. X        *dml += -3.767e-3*c2x7*sx3-(3.3839e-2+1.125e-3*x1)*cx7*sx3-
  1846. X          4.261e-3*s2x7*cx3+
  1847. X          (1.161e-3*x1-6.333e-3)*cx7*cx3+
  1848. X          2.178e-3*cx3-6.675e-3*c2x7*cx3-2.664e-3*c3x7*cx3-
  1849. X          2.572e-3*sx7*s2x3-3.567e-3*s2x7*s2x3+2.094e-3*cx7*c2x3+
  1850. X          3.342e-3*c2x7*c2x3;
  1851. X    *dml = degrad(*dml);
  1852. X
  1853. X    *ds = (3606+(130-43*x1)*x1)*sx5+(1289-580*x1)*cx5-6764*sx7*sx3-
  1854. X         1110*s2x7*sx3-224*s3x7*sx3-204*sx3+(1284+116*x1)*cx7*sx3+
  1855. X         188*c2x7*sx3+(1460+130*x1)*sx7*cx3+224*s2x7*cx3-817*cx3+
  1856. X         6074*cx3*cx7+992*c2x7*cx3+
  1857. X         508*c3x7*cx3+230*c4x7*cx3+108*c5x7*cx3;
  1858. X    *ds += -(956+73*x1)*sx7*s2x3+448*s2x7*s2x3+137*s3x7*s2x3+
  1859. X         (108*x1-997)*cx7*s2x3+480*c2x7*s2x3+148*c3x7*s2x3+
  1860. X         (99*x1-956)*sx7*c2x3+490*s2x7*c2x3+
  1861. X         158*s3x7*c2x3+179*c2x3+(1024+75*x1)*cx7*c2x3-
  1862. X         437*c2x7*c2x3-132*c3x7*c2x3;
  1863. X    *ds *= 1e-7;
  1864. X
  1865. X    dp = (7.192e-3-3.147e-3*x1)*sx5-4.344e-3*sx3+
  1866. X         (x1*(1.97e-4*x1-6.75e-4)-2.0428e-2)*cx5+
  1867. X         3.4036e-2*cx7*sx3+(7.269e-3+6.72e-4*x1)*sx7*sx3+
  1868. X         5.614e-3*c2x7*sx3+2.964e-3*c3x7*sx3+3.7761e-2*sx7*cx3+
  1869. X         6.158e-3*s2x7*cx3-
  1870. X         6.603e-3*cx7*cx3-5.356e-3*sx7*s2x3+2.722e-3*s2x7*s2x3+
  1871. X         4.483e-3*cx7*s2x3-2.642e-3*c2x7*s2x3+4.403e-3*sx7*c2x3-
  1872. X         2.536e-3*s2x7*c2x3+5.547e-3*cx7*c2x3-2.689e-3*c2x7*c2x3;
  1873. X
  1874. X    *dm = *dml-(degrad(dp)/s);
  1875. X
  1876. X    *da = 205*cx7-263*cx5+693*c2x7+312*c3x7+147*c4x7+299*sx7*sx3+
  1877. X         181*c2x7*sx3+204*s2x7*cx3+111*s3x7*cx3-337*cx7*cx3-
  1878. X         111*c2x7*cx3;
  1879. X    *da *= 1e-6;
  1880. X}
  1881. X
  1882. X/* ....saturn */
  1883. Xstatic void
  1884. Xp_saturn (t, s, dml, ds, dm, da, dhl)
  1885. Xdouble t, s;
  1886. Xdouble *dml, *ds, *dm, *da, *dhl;
  1887. X{
  1888. X    double dp;
  1889. X    double x1, x2, x3, x4, x5, x6, x7, x8;
  1890. X    double sx3, cx3, s2x3, c2x3, s3x3, c3x3, s4x3, c4x3;
  1891. X        double sx5, cx5, s2x5, c2x5;
  1892. X    double sx6;
  1893. X        double sx7, cx7, s2x7, c2x7, s3x7, c3x7, s4x7, c4x7, c5x7, s5x7;
  1894. X    double s2x8, c2x8, s3x8, c3x8;
  1895. X
  1896. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  1897. X        x7 = x3-x2;
  1898. X    sx3 = sin(x3);
  1899. X    cx3 = cos(x3);
  1900. X        s2x3 = sin(2*x3);
  1901. X    c2x3 = cos(2*x3);
  1902. X        sx5 = sin(x5);
  1903. X    cx5 = cos(x5);
  1904. X        s2x5 = sin(2*x5);
  1905. X    sx6 = sin(x6);
  1906. X        sx7 = sin(x7);
  1907. X    cx7 = cos(x7);
  1908. X        s2x7 = sin(2*x7);
  1909. X    c2x7 = cos(2*x7);
  1910. X        s3x7 = sin(3*x7);
  1911. X    c3x7 = cos(3*x7);
  1912. X        s4x7 = sin(4*x7);
  1913. X    c4x7 = cos(4*x7);
  1914. X        c5x7 = cos(5*x7);
  1915. X
  1916. X    s3x3 = sin(3*x3);
  1917. X    c3x3 = cos(3*x3);
  1918. X    s4x3 = sin(4*x3);
  1919. X    c4x3 = cos(4*x3);
  1920. X    c2x5 = cos(2*x5);
  1921. X    s5x7 = sin(5*x7);
  1922. X    x8 = x4-x3;
  1923. X    s2x8 = sin(2*x8);
  1924. X    c2x8 = cos(2*x8);
  1925. X    s3x8 = sin(3*x8);
  1926. X    c3x8 = cos(3*x8);
  1927. X
  1928. X    *dml = 7.581e-3*s2x5-7.986e-3*sx6-1.48811e-1*sx7-4.0786e-2*s2x7-
  1929. X          (8.14181e-1-(1.815e-2-1.6714e-2*x1)*x1)*sx5-
  1930. X          (1.0497e-2-(1.60906e-1-4.1e-3*x1)*x1)*cx5-1.5208e-2*s3x7-
  1931. X          6.339e-3*s4x7-6.244e-3*sx3-1.65e-2*s2x7*sx3+
  1932. X          (8.931e-3+2.728e-3*x1)*sx7*sx3-5.775e-3*s3x7*sx3+
  1933. X          (8.1344e-2+3.206e-3*x1)*cx7*sx3+1.5019e-2*c2x7*sx3;
  1934. X    *dml += (8.5581e-2+2.494e-3*x1)*sx7*cx3+1.4394e-2*c2x7*cx3+
  1935. X          (2.5328e-2-3.117e-3*x1)*cx7*cx3+
  1936. X          6.319e-3*c3x7*cx3+6.369e-3*sx7*s2x3+9.156e-3*s2x7*s2x3+
  1937. X          7.525e-3*s3x8*s2x3-5.236e-3*cx7*c2x3-7.736e-3*c2x7*c2x3-
  1938. X          7.528e-3*c3x8*c2x3;
  1939. X    *dml = degrad(*dml);
  1940. X
  1941. X    *ds = (-7927+(2548+91*x1)*x1)*sx5+(13381+(1226-253*x1)*x1)*cx5+
  1942. X         (248-121*x1)*s2x5-(305+91*x1)*c2x5+412*s2x7+12415*sx3+
  1943. X         (390-617*x1)*sx7*sx3+(165-204*x1)*s2x7*sx3+26599*cx7*sx3-
  1944. X         4687*c2x7*sx3-1870*c3x7*sx3-821*c4x7*sx3-
  1945. X         377*c5x7*sx3+497*c2x8*sx3+(163-611*x1)*cx3;
  1946. X    *ds += -12696*sx7*cx3-4200*s2x7*cx3-1503*s3x7*cx3-619*s4x7*cx3-
  1947. X         268*s5x7*cx3-(282+1306*x1)*cx7*cx3+(-86+230*x1)*c2x7*cx3+
  1948. X         461*s2x8*cx3-350*s2x3+(2211-286*x1)*sx7*s2x3-
  1949. X         2208*s2x7*s2x3-568*s3x7*s2x3-346*s4x7*s2x3-
  1950. X         (2780+222*x1)*cx7*s2x3+(2022+263*x1)*c2x7*s2x3+248*c3x7*s2x3+
  1951. X         242*s3x8*s2x3+467*c3x8*s2x3-490*c2x3-(2842+279*x1)*sx7*c2x3;
  1952. X    *ds += (128+226*x1)*s2x7*c2x3+224*s3x7*c2x3+
  1953. X         (-1594+282*x1)*cx7*c2x3+(2162-207*x1)*c2x7*c2x3+
  1954. X         561*c3x7*c2x3+343*c4x7*c2x3+469*s3x8*c2x3-242*c3x8*c2x3-
  1955. X         205*sx7*s3x3+262*s3x7*s3x3+208*cx7*c3x3-271*c3x7*c3x3-
  1956. X         382*c3x7*s4x3-376*s3x7*c4x3;
  1957. X    *ds *= 1e-7;
  1958. X
  1959. X    dp = (7.7108e-2+(7.186e-3-1.533e-3*x1)*x1)*sx5-7.075e-3*sx7+
  1960. X         (4.5803e-2-(1.4766e-2+5.36e-4*x1)*x1)*cx5-7.2586e-2*cx3-
  1961. X         7.5825e-2*sx7*sx3-2.4839e-2*s2x7*sx3-8.631e-3*s3x7*sx3-
  1962. X         1.50383e-1*cx7*cx3+2.6897e-2*c2x7*cx3+1.0053e-2*c3x7*cx3-
  1963. X         (1.3597e-2+1.719e-3*x1)*sx7*s2x3+1.1981e-2*s2x7*c2x3;
  1964. X    dp += -(7.742e-3-1.517e-3*x1)*cx7*s2x3+
  1965. X         (1.3586e-2-1.375e-3*x1)*c2x7*c2x3-
  1966. X         (1.3667e-2-1.239e-3*x1)*sx7*c2x3+
  1967. X         (1.4861e-2+1.136e-3*x1)*cx7*c2x3-
  1968. X         (1.3064e-2+1.628e-3*x1)*c2x7*c2x3;
  1969. X
  1970. X    *dm = *dml-(degrad(dp)/s);
  1971. X
  1972. X    *da = 572*sx5-1590*s2x7*cx3+2933*cx5-647*s3x7*cx3+33629*cx7-
  1973. X         344*s4x7*cx3-3081*c2x7+2885*cx7*cx3-1423*c3x7+
  1974. X         (2172+102*x1)*c2x7*cx3-671*c4x7+296*c3x7*cx3-320*c5x7-
  1975. X         267*s2x7*s2x3+1098*sx3-778*cx7*s2x3-2812*sx7*sx3;
  1976. X    *da += 495*c2x7*s2x3+688*s2x7*sx3+250*c3x7*s2x3-393*s3x7*sx3-
  1977. X         856*sx7*c2x3-228*s4x7*sx3+441*s2x7*c2x3+2138*cx7*sx3+
  1978. X         296*c2x7*c2x3-999*c2x7*sx3+211*c3x7*c2x3-642*c3x7*sx3-
  1979. X         427*sx7*s3x3-325*c4x7*sx3+398*s3x7*s3x3-890*cx3+
  1980. X         344*cx7*c3x3+2206*sx7*cx3-427*c3x7*c3x3;
  1981. X    *da *= 1e-6;
  1982. X
  1983. X    *dhl = 7.47e-4*cx7*sx3+1.069e-3*cx7*cx3+2.108e-3*s2x7*s2x3+
  1984. X          1.261e-3*c2x7*s2x3+1.236e-3*s2x7*c2x3-2.075e-3*c2x7*c2x3;
  1985. X    *dhl = degrad(*dhl);
  1986. X}
  1987. X
  1988. X/* ....uranus */
  1989. Xstatic void
  1990. Xp_uranus (t, s, dl, dr, dml, ds, dm, da, dhl)
  1991. Xdouble t, s;
  1992. Xdouble *dl, *dr, *dml, *ds, *dm, *da, *dhl;
  1993. X{
  1994. X    double dp;
  1995. X    double x1, x2, x3, x4, x5, x6;
  1996. X    double x8, x9, x10, x11, x12;
  1997. X    double sx4, cx4, s2x4, c2x4;
  1998. X    double sx9, cx9, s2x9, c2x9;
  1999. X    double sx11, cx11;
  2000. X
  2001. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  2002. X
  2003. X        x8 = mod2PI(1.46205+3.81337*t);
  2004. X        x9 = 2*x8-x4;
  2005. X    sx9 = sin(x9);
  2006. X    cx9 = cos(x9);
  2007. X        s2x9 = sin(2*x9);
  2008. X    c2x9 = cos(2*x9);
  2009. X
  2010. X    x10 = x4-x2;
  2011. X    x11 = x4-x3;
  2012. X    x12 = x8-x4;
  2013. X
  2014. X    *dml = (8.64319e-1-1.583e-3*x1)*sx9+(8.2222e-2-6.833e-3*x1)*cx9+
  2015. X          3.6017e-2*s2x9-3.019e-3*c2x9+8.122e-3*sin(x6);
  2016. X    *dml = degrad(*dml);
  2017. X
  2018. X    dp = 1.20303e-1*sx9+6.197e-3*s2x9+(1.9472e-2-9.47e-4*x1)*cx9;
  2019. X    *dm = *dml-(degrad(dp)/s);
  2020. X
  2021. X    *ds = (163*x1-3349)*sx9+20981*cx9+1311*c2x9;
  2022. X    *ds *= 1e-7;
  2023. X
  2024. X    *da = -3.825e-3*cx9;
  2025. X
  2026. X    *dl = (1.0122e-2-9.88e-4*x1)*sin(x4+x11)+
  2027. X         (-3.8581e-2+(2.031e-3-1.91e-3*x1)*x1)*cos(x4+x11)+
  2028. X         (3.4964e-2-(1.038e-3-8.68e-4*x1)*x1)*cos(2*x4+x11)+
  2029. X         5.594e-3*sin(x4+3*x12)-1.4808e-2*sin(x10)-
  2030. X         5.794e-3*sin(x11)+2.347e-3*cos(x11)+9.872e-3*sin(x12)+
  2031. X         8.803e-3*sin(2*x12)-4.308e-3*sin(3*x12);
  2032. X
  2033. X    sx11 = sin(x11);
  2034. X    cx11 = cos(x11);
  2035. X    sx4 = sin(x4);
  2036. X    cx4 = cos(x4);
  2037. X    s2x4 = sin(2*x4);
  2038. X    c2x4 = cos(2*x4);
  2039. X    *dhl = (4.58e-4*sx11-6.42e-4*cx11-5.17e-4*cos(4*x12))*sx4-
  2040. X          (3.47e-4*sx11+8.53e-4*cx11+5.17e-4*sin(4*x11))*cx4+
  2041. X          4.03e-4*(cos(2*x12)*s2x4+sin(2*x12)*c2x4);
  2042. X    *dhl = degrad(*dhl);
  2043. X
  2044. X    *dr = -25948+4985*cos(x10)-1230*cx4+3354*cos(x11)+904*cos(2*x12)+
  2045. X         894*(cos(x12)-cos(3*x12))+(5795*cx4-1165*sx4+1388*c2x4)*sx11+
  2046. X         (1351*cx4+5702*sx4+1388*s2x4)*cos(x11);
  2047. X    *dr *= 1e-6;
  2048. X}
  2049. X
  2050. X/* ....neptune */
  2051. Xstatic void
  2052. Xp_neptune (t, s, dl, dr, dml, ds, dm, da, dhl)
  2053. Xdouble t, s;
  2054. Xdouble *dl, *dr, *dml, *ds, *dm, *da, *dhl;
  2055. X{
  2056. X    double dp;
  2057. X    double x1, x2, x3, x4, x5, x6;
  2058. X    double x8, x9, x10, x11, x12;
  2059. X    double sx8, cx8;
  2060. X    double sx9, cx9, s2x9, c2x9;
  2061. X    double s2x12, c2x12;
  2062. X
  2063. X    aux_jsun (t, &x1, &x2, &x3, &x4, &x5, &x6);
  2064. X
  2065. X        x8 = mod2PI(1.46205+3.81337*t);
  2066. X        x9 = 2*x8-x4;
  2067. X    sx9 = sin(x9);
  2068. X    cx9 = cos(x9);
  2069. X        s2x9 = sin(2*x9);
  2070. X    c2x9 = cos(2*x9);
  2071. X
  2072. X    x10 = x8-x2;
  2073. X    x11 = x8-x3;
  2074. X    x12 = x8-x4;
  2075. X
  2076. X    *dml = (1.089e-3*x1-5.89833e-1)*sx9+(4.658e-3*x1-5.6094e-2)*cx9-
  2077. X          2.4286e-2*s2x9;
  2078. X    *dml = degrad(*dml);
  2079. X
  2080. X    dp = 2.4039e-2*sx9-2.5303e-2*cx9+6.206e-3*s2x9-5.992e-3*c2x9;
  2081. X
  2082. X    *dm = *dml-(degrad(dp)/s);
  2083. X
  2084. X    *ds = 4389*sx9+1129*s2x9+4262*cx9+1089*c2x9;
  2085. X    *ds *= 1e-7;
  2086. X
  2087. X    *da = 8189*cx9-817*sx9+781*c2x9;
  2088. X    *da *= 1e-6;
  2089. X
  2090. X    s2x12 = sin(2*x12);
  2091. X    c2x12 = cos(2*x12);
  2092. X    sx8 = sin(x8);
  2093. X    cx8 = cos(x8);
  2094. X    *dl = -9.556e-3*sin(x10)-5.178e-3*sin(x11)+2.572e-3*s2x12-
  2095. X         2.972e-3*c2x12*sx8-2.833e-3*s2x12*cx8;
  2096. X
  2097. X    *dhl = 3.36e-4*c2x12*sx8+3.64e-4*s2x12*cx8;
  2098. X    *dhl = degrad(*dhl);
  2099. X
  2100. X    *dr = -40596+4992*cos(x10)+2744*cos(x11)+2044*cos(x12)+1051*c2x12;
  2101. X    *dr *= 1e-6;
  2102. X}
  2103. END_OF_FILE
  2104.   if test 19091 -ne `wc -c <'plans.c'`; then
  2105.     echo shar: \"'plans.c'\" unpacked with wrong size!
  2106.   fi
  2107.   # end of 'plans.c'
  2108. fi
  2109. if test -f 'skyfiltmenu.c' -a "${1}" != "-c" ; then 
  2110.   echo shar: Will not clobber existing file \"'skyfiltmenu.c'\"
  2111. else
  2112.   echo shar: Extracting \"'skyfiltmenu.c'\" \(16767 characters\)
  2113.   sed "s/^X//" >'skyfiltmenu.c' <<'END_OF_FILE'
  2114. X/* code to manage the stuff on the sky view filter display.
  2115. X */
  2116. X
  2117. X#include <stdio.h>
  2118. X#include <ctype.h>
  2119. X#include <math.h>
  2120. X#if defined(__STDC__)
  2121. X#include <stdlib.h>
  2122. X#endif
  2123. X#include <X11/Xlib.h>
  2124. X#include <Xm/Xm.h>
  2125. X#include <Xm/Form.h>
  2126. X#include <Xm/Frame.h>
  2127. X#include <Xm/DrawingA.h>
  2128. X#include <Xm/Label.h>
  2129. X#include <Xm/PushB.h>
  2130. X#include <Xm/RowColumn.h>
  2131. X#include <Xm/ToggleB.h>
  2132. X#include <Xm/Text.h>
  2133. X#include <Xm/Scale.h>
  2134. X#include <Xm/Separator.h>
  2135. X#include "astro.h"
  2136. X#include "circum.h"
  2137. X
  2138. X/* info for each filter option toggle */
  2139. Xtypedef struct {
  2140. X    char *label;    /* label on the toggle button */
  2141. X    char *name;        /* name of toggle button, for resource setting */
  2142. X    int type;        /* as in Obj.type */
  2143. X    char class;        /* as in Obj.f.f_class */
  2144. X    char state;        /* 0 or 1 depending on whether this class is on */
  2145. X    Widget tbw;        /* the toggle button widget */
  2146. X} FilterTB;
  2147. X
  2148. X/* info for a set of filters forming a category */
  2149. Xtypedef struct {
  2150. X    char *label;    /* label for this category */
  2151. X    FilterTB *ftb;    /* array of toggle button filters in this class */
  2152. X    int nftb;        /* entries in ftb[] */
  2153. X    Widget pbw;        /* the category "toggle" pushbutton */
  2154. X} FilterCat;
  2155. X
  2156. X#if defined(__STDC__) || defined(__cplusplus)
  2157. X#define P_(s) s
  2158. X#else
  2159. X#define P_(s) ()
  2160. X#endif
  2161. X
  2162. Xextern Now *mm_get_now P_((void));
  2163. Xextern void get_something P_((Widget w, char *resource, char *value));
  2164. Xextern void prompt_map_cb P_((Widget w, XtPointer client, XtPointer call));
  2165. Xextern void sv_all P_((Now *np, int preclr));
  2166. Xextern void sv_draw_obj P_((Display *dsp, Drawable win, GC gc, Obj *op, int x, int y, int diam, int dotsonly));
  2167. X
  2168. Xvoid svf_create P_((void));
  2169. Xvoid svf_manage_toggle P_((void));
  2170. Xvoid svf_manage P_((void));
  2171. Xvoid svf_unmanage P_((void));
  2172. Xint svf_filter_ok P_((Obj *op));
  2173. Xvoid svf_cursor P_((Cursor c));
  2174. Xstatic void svf_create_filter P_((Widget mainrc, FilterCat *fcp));
  2175. Xstatic void svf_reset P_((void));
  2176. Xstatic void svf_apply P_((void));
  2177. Xstatic void svf_da_cb P_((Widget w, XtPointer client, XtPointer call));
  2178. Xstatic void svf_draw_symbol P_((FilterTB *ftbp, Widget daw));
  2179. Xstatic void svf_apply_cb P_((Widget w, XtPointer client, XtPointer call));
  2180. Xstatic void svf_ok_cb P_((Widget w, XtPointer client, XtPointer call));
  2181. Xstatic void svf_close_cb P_((Widget w, XtPointer client, XtPointer call));
  2182. Xstatic void svf_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  2183. Xstatic void svf_all_cb P_((Widget w, XtPointer client, XtPointer call));
  2184. Xstatic void svf_reset_cb P_((Widget w, XtPointer client, XtPointer call));
  2185. Xstatic void svf_cat_toggle_cb P_((Widget w, XtPointer client, XtPointer call));
  2186. X
  2187. X#undef P_
  2188. X
  2189. Xextern Widget toplevel_w;
  2190. X#define    XtD    XtDisplay(toplevel_w)
  2191. X
  2192. Xstatic FilterTB solsys_f[] = {
  2193. X    {"Planets",        "Planets",    PLANET,        0},
  2194. X    {"Elliptical",    "Elliptical",    ELLIPTICAL,    0},
  2195. X    {"Hyperbolic",    "Hyperbolic",    HYPERBOLIC,    0},
  2196. X    {"Parabolic",    "Parabolic",    PARABOLIC,    0}
  2197. X};
  2198. X
  2199. Xstatic FilterTB other_f[] = {
  2200. X    {"Q Quasars",     "Quasars",    FIXED,        'Q'},
  2201. X    {"T Stellar",    "Stellar",    FIXED,        'T'},
  2202. X    {"Undefined",    "Undefined",    FIXED,        '\0'}
  2203. X};
  2204. X
  2205. Xstatic FilterTB stars_f[] = {
  2206. X    {"S Single",    "Stars",    FIXED,        'S'},
  2207. X    {"B Binary",    "Binary",    FIXED,        'B'},
  2208. X    {"D Double",    "Double",    FIXED,        'D'},
  2209. X    {"M Multiple",    "Multiple",    FIXED,        'M'},
  2210. X    {"V Variable",    "Variable",    FIXED,        'V'}
  2211. X};
  2212. X
  2213. Xstatic FilterTB nebulea_f[] = {
  2214. X    {"N Bright",    "BrightNeb",    FIXED,        'N'},
  2215. X    {"F Diffuse",    "DiffuseNeb",    FIXED,        'F'},
  2216. X    {"K Dark",        "DarkNeb",    FIXED,        'K'},
  2217. X    {"P Planetary",    "PlanetaryNeb",    FIXED,        'P'}
  2218. X};
  2219. X
  2220. Xstatic FilterTB galaxies_f[] = {
  2221. X    {"G Spiral",    "SpiralGal",    FIXED,        'G'},
  2222. X    {"H Spherical",    "SphericalGal",    FIXED,        'H'},
  2223. X    {"A Clusters",    "GalClusters",    FIXED,        'A'}
  2224. X};
  2225. X
  2226. Xstatic FilterTB clusters_f[] = {
  2227. X    {"C Globular",    "GlobularCl",    FIXED,        'C'},
  2228. X    {"O Open",        "OpenCl",    FIXED,        'O'},
  2229. X    {"U in Nebula",    "ClInNeb",    FIXED,        'U'}
  2230. X};
  2231. X
  2232. Xstatic FilterCat filters[] = {
  2233. X    {"Solar System:",    solsys_f,    XtNumber(solsys_f)},
  2234. X    {"Clusters:",    clusters_f,    XtNumber(clusters_f)},
  2235. X    {"Galaxies:",    galaxies_f,    XtNumber(galaxies_f)},
  2236. X    {"Nebulea:",    nebulea_f,    XtNumber(nebulea_f)},
  2237. X    {"Stars:",        stars_f,    XtNumber(stars_f)},
  2238. X    {"Other:",        other_f,    XtNumber(other_f)}
  2239. X};
  2240. X
  2241. X/* these form rapid lookup tables for the state of an object.
  2242. X * they can be directly indexed by Obj.type and Obj.f.f_class, respectively.
  2243. X */
  2244. Xstatic char fclass_table[128];
  2245. Xstatic char type_table[10];
  2246. X
  2247. Xstatic Widget filter_w;
  2248. X
  2249. X/* create, but do not manage, the filter dialog.
  2250. X * we also apply its state info immediately to the initial resource
  2251. X * settings of the toggle buttons are used to set up the real filter
  2252. X * right away.
  2253. X */
  2254. Xvoid
  2255. Xsvf_create()
  2256. X{
  2257. X    static struct {
  2258. X        char *name;
  2259. X        void (*cb)();
  2260. X    } ctls[] = {
  2261. X        {"Ok", svf_ok_cb},
  2262. X        {"Apply", svf_apply_cb},
  2263. X        {"All", svf_all_cb},
  2264. X        {"Toggle All", svf_toggle_cb},
  2265. X        {"Reset", svf_reset_cb},
  2266. X        {"Close", svf_close_cb}
  2267. X    };
  2268. X    Arg args[20];
  2269. X    XmString str;
  2270. X    Widget w;
  2271. X    Widget ctlf_w;
  2272. X    Widget topsep_w, botsep_w;
  2273. X    Widget hrc_w;
  2274. X    int n;
  2275. X    int i;
  2276. X
  2277. X    /* create form */
  2278. X    n = 0;
  2279. X    XtSetArg (args[n], XmNautoUnmanage, False); n++;
  2280. X    XtSetArg (args[n], XmNdefaultPosition, False); n++;
  2281. X    filter_w = XmCreateFormDialog (toplevel_w, "SkyFilter", args, n);
  2282. X    XtAddCallback (filter_w, XmNmapCallback, prompt_map_cb, NULL);
  2283. X
  2284. X    /* set some stuff in the parent DialogShell.
  2285. X     * setting XmNdialogTitle in the Form didn't work..
  2286. X     */
  2287. X    n = 0;
  2288. X    XtSetArg (args[n], XmNtitle, "xephem Sky view Filter"); n++;
  2289. X    XtSetValues (XtParent(filter_w), args, n);
  2290. X
  2291. X    /* make a separator across the top */
  2292. X
  2293. X    n = 0;
  2294. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2295. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2296. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2297. X    topsep_w = XmCreateSeparator (filter_w, "TopSep", args, n);
  2298. X    XtManageChild (topsep_w);
  2299. X
  2300. X    /* make a form for bottom control panel */
  2301. X
  2302. X    n = 0;
  2303. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2304. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2305. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2306. X    XtSetArg (args[n], XmNfractionBase, 25); n++;
  2307. X    XtSetArg (args[n], XmNverticalSpacing, 5); n++;
  2308. X    ctlf_w = XmCreateForm (filter_w, "SVControlF", args, n);
  2309. X    XtManageChild (ctlf_w);
  2310. X
  2311. X        /* add the control buttons */
  2312. X
  2313. X        for (i = 0; i < XtNumber(ctls); i++) {
  2314. X        str = XmStringCreateLtoR(ctls[i].name,XmSTRING_DEFAULT_CHARSET);
  2315. X        n = 0;
  2316. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
  2317. X        XtSetArg (args[n], XmNleftPosition, 1+i*4); n++;
  2318. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
  2319. X        XtSetArg (args[n], XmNrightPosition, 4+i*4); n++;
  2320. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2321. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2322. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2323. X        w = XmCreatePushButton (ctlf_w, "FilterCB", args, n);
  2324. X        XtManageChild(w);
  2325. X        XmStringFree (str);
  2326. X        XtAddCallback (w, XmNactivateCallback, ctls[i].cb, NULL);
  2327. X        }
  2328. X
  2329. X    /* put a separator on top of the control panel */
  2330. X
  2331. X    n = 0;
  2332. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2333. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2334. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2335. X    XtSetArg (args[n], XmNbottomWidget, ctlf_w); n++;
  2336. X    botsep_w = XmCreateSeparator (filter_w, "BotSep", args, n);
  2337. X    XtManageChild (botsep_w);
  2338. X
  2339. X    /* make a horizontal rowcol to contain each column */
  2340. X
  2341. X    n = 0;
  2342. X    XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2343. X    XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2344. X    XtSetArg (args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
  2345. X    XtSetArg (args[n], XmNbottomWidget, botsep_w); n++;
  2346. X    XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2347. X    XtSetArg (args[n], XmNtopWidget, topsep_w); n++;
  2348. X    XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
  2349. X    XtSetArg (args[n], XmNpacking, XmPACK_TIGHT); n++;
  2350. X    XtSetArg (args[n], XmNspacing, 0); n++;
  2351. X    XtSetArg (args[n], XmNmarginWidth, 0); n++;
  2352. X    hrc_w = XmCreateRowColumn (filter_w, "CategoryTableRC", args, n);
  2353. X    XtManageChild (hrc_w);
  2354. X
  2355. X    /* fill the horizontal rc with each FilterCat */
  2356. X
  2357. X    for (i = 0; i < XtNumber(filters); i++)
  2358. X        svf_create_filter (hrc_w, &filters[i]);
  2359. X
  2360. X    /* set the real filter according to the state of the toggle buttons */
  2361. X    svf_apply();
  2362. X}
  2363. X
  2364. X/* called to toggle whether the filter dialog is up.
  2365. X * whenever we are managed, reset the state of the toggle buttons back
  2366. X * to the way the real filter is.
  2367. X */
  2368. Xvoid
  2369. Xsvf_manage_toggle ()
  2370. X{
  2371. X    if (XtIsManaged(filter_w))
  2372. X        svf_unmanage();
  2373. X    else
  2374. X        svf_manage();
  2375. X}
  2376. X
  2377. X/* called to manage the filer dialog.
  2378. X * whenever we are managed, reset the state of the toggle buttons back
  2379. X * to the way the real filter is.
  2380. X */
  2381. Xvoid
  2382. Xsvf_manage()
  2383. X{
  2384. X    svf_reset();
  2385. X    XtManageChild(filter_w);
  2386. X}
  2387. X
  2388. Xvoid
  2389. Xsvf_unmanage()
  2390. X{
  2391. X    XtUnmanageChild(filter_w);
  2392. X}
  2393. X
  2394. X/* return 1 if p satisfies the stuff in the filter dialog, else 0.
  2395. X * N.B. because svf_apply() has to have already been called we do not need
  2396. X *   to range check the type and class.
  2397. X */
  2398. Xsvf_filter_ok (op)
  2399. XObj *op;
  2400. X{
  2401. X    int t = op->type;
  2402. X
  2403. X    if (t == FIXED)
  2404. X        return (fclass_table[op->f_class]);
  2405. X    else
  2406. X        return (type_table[t]);
  2407. X}
  2408. X
  2409. X/* called to put up or remove the watch cursor.  */
  2410. Xvoid
  2411. Xsvf_cursor (c)
  2412. XCursor c;
  2413. X{
  2414. X    Window win;
  2415. X
  2416. X    if (filter_w && (win = XtWindow(filter_w))) {
  2417. X        Display *dsp = XtDisplay(filter_w);
  2418. X        if (c)
  2419. X        XDefineCursor (dsp, win, c);
  2420. X        else
  2421. X        XUndefineCursor (dsp, win);
  2422. X    }
  2423. X}
  2424. X
  2425. X/* create one FilterCat filter category in the given RowColumn */
  2426. Xstatic void
  2427. Xsvf_create_filter (mainrc, fcp)
  2428. XWidget mainrc;
  2429. XFilterCat *fcp;
  2430. X{
  2431. X    Arg args[20];
  2432. X    Widget l_w;
  2433. X    Widget rc_w;    /* rc for the label and controls */
  2434. X    Widget fr_w, da_w;
  2435. X    Widget w;
  2436. X    int n;
  2437. X    int i;
  2438. X
  2439. X    /* make a rc within a frame for the tb rowcol */
  2440. X
  2441. X    n = 0;
  2442. X    fr_w = XmCreateFrame (mainrc, "Frame", args, n);
  2443. X    XtManageChild (fr_w);
  2444. X    n = 0;
  2445. X    XtSetArg (args[n], XmNmarginWidth, 0); n++;
  2446. X    XtSetArg (args[n], XmNisAligned, False); n++;
  2447. X    rc_w = XmCreateRowColumn (fr_w, "CategoryRC", args, n);
  2448. X    XtManageChild (rc_w);
  2449. X
  2450. X    /* make a label for the category */
  2451. X
  2452. X    n = 0;
  2453. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2454. X    l_w = XmCreateLabel (rc_w, fcp->label, args, n);
  2455. X    XtManageChild (l_w);
  2456. X
  2457. X    /* make a pushbutton used to toggle all entries in this category */
  2458. X    n = 0;
  2459. X    XtSetArg (args[n], XmNalignment, XmALIGNMENT_CENTER); n++;
  2460. X    w = XmCreatePushButton (rc_w, "Toggle", args, n);
  2461. X    XtAddCallback (w, XmNactivateCallback, svf_cat_toggle_cb,
  2462. X                                (XtPointer)fcp);
  2463. X    XtManageChild (w);
  2464. X
  2465. X    /* add each filter */
  2466. X
  2467. X    for (i = 0; i < fcp->nftb; i++) {
  2468. X        Widget f_w;
  2469. X        Widget tb_w;
  2470. X        FilterTB *ftbp = &fcp->ftb[i];
  2471. X        XmString str;
  2472. X
  2473. X        n = 0;
  2474. X        f_w = XmCreateForm (rc_w, "FTBF", args, n);
  2475. X        XtManageChild (f_w);
  2476. X
  2477. X        /* create a frame around a drawing area in which to show the
  2478. X         * object symbol
  2479. X         */
  2480. X        n = 0;
  2481. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2482. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2483. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  2484. X        XtSetArg (args[n], XmNshadowType, XmSHADOW_ETCHED_OUT); n++;
  2485. X        fr_w = XmCreateFrame (f_w, "SymbolF", args, n);
  2486. X        XtManageChild (fr_w);
  2487. X        n = 0;
  2488. X        da_w = XmCreateDrawingArea (fr_w, "SymbolDA", args, n);
  2489. X        XtAddCallback (da_w, XmNexposeCallback, svf_da_cb,
  2490. X                                (XtPointer)ftbp);
  2491. X        XtManageChild (da_w);
  2492. X
  2493. X        /* create the filter selection toggle button */
  2494. X
  2495. X        str = XmStringCreateLtoR (ftbp->label,XmSTRING_DEFAULT_CHARSET);
  2496. X        n = 0;
  2497. X        XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  2498. X        XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  2499. X        XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2500. X        XtSetArg (args[n], XmNleftWidget, fr_w); n++;
  2501. X        XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  2502. X        XtSetArg (args[n], XmNlabelString, str); n++;
  2503. X        XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
  2504. X        tb_w = XmCreateToggleButton (f_w, ftbp->name, args, n);
  2505. X        XmStringFree(str);
  2506. X        XtManageChild (tb_w);
  2507. X        ftbp->tbw = tb_w;
  2508. X    }
  2509. X}
  2510. X
  2511. X/* set the toggle button states according to the real filter states.
  2512. X */
  2513. Xstatic void
  2514. Xsvf_reset()
  2515. X{
  2516. X    int i, j;
  2517. X
  2518. X    for (i = 0; i < XtNumber(filters); i++) {
  2519. X        FilterCat *fcp = &filters[i];
  2520. X        for (j = 0; j < fcp->nftb; j++) {
  2521. X        FilterTB *ftbp = &fcp->ftb[j];
  2522. X        XmToggleButtonSetState (ftbp->tbw, ftbp->state, True);
  2523. X        }
  2524. X    }
  2525. X}
  2526. X
  2527. X/* set the filter according to the present state of the toggle buttons.
  2528. X */
  2529. Xstatic void
  2530. Xsvf_apply()
  2531. X{
  2532. X    int i, j;
  2533. X
  2534. X    for (i = 0; i < XtNumber(filters); i++) {
  2535. X        FilterCat *fcp = &filters[i];
  2536. X        for (j = 0; j < fcp->nftb; j++) {
  2537. X        FilterTB *ftbp = &fcp->ftb[j];
  2538. X        int t = ftbp->type;
  2539. X        if (t < 0 || t >= XtNumber(type_table)) {
  2540. X            printf ("svf_apply: type out of range: %d\n", t);
  2541. X            exit (1);
  2542. X        }
  2543. X        ftbp->state = XmToggleButtonGetState (ftbp->tbw);
  2544. X        if (ftbp->type == FIXED) {
  2545. X            int c = ftbp->class;
  2546. X            if (c < 0 || c >= XtNumber(fclass_table)) {
  2547. X            printf ("svf_apply: FIXED class out of range: %d\n", c);
  2548. X            exit (1);
  2549. X            }
  2550. X            fclass_table[c] = ftbp->state;
  2551. X        } else
  2552. X            type_table[t] = ftbp->state;
  2553. X        }
  2554. X    }
  2555. X}
  2556. X
  2557. X/* called when a symbol drawing area is exposed.
  2558. X * client is a pointer to the FilterTB.
  2559. X */
  2560. X/* ARGSUSED */
  2561. Xstatic void
  2562. Xsvf_da_cb (w, client, call)
  2563. XWidget w;
  2564. XXtPointer client;
  2565. XXtPointer call;
  2566. X{
  2567. X    XmDrawingAreaCallbackStruct *c = (XmDrawingAreaCallbackStruct *)call;
  2568. X    FilterTB *ftbp = (FilterTB *) client;
  2569. X
  2570. X    switch (c->reason) {
  2571. X    case XmCR_EXPOSE: {
  2572. X        /* turn off gravity so we get expose events for either shrink or
  2573. X         * expand.
  2574. X         */
  2575. X        static before;
  2576. X        XExposeEvent *e = &c->event->xexpose;
  2577. X
  2578. X        if (!before) {
  2579. X        XSetWindowAttributes swa;
  2580. X        swa.bit_gravity = ForgetGravity;
  2581. X        XChangeWindowAttributes (e->display, e->window, 
  2582. X                                CWBitGravity, &swa);
  2583. X        before = 1;
  2584. X        }
  2585. X        /* wait for the last in the series */
  2586. X        if (e->count != 0)
  2587. X        return;
  2588. X        }
  2589. X        break;
  2590. X    default:
  2591. X        return;
  2592. X    }
  2593. X
  2594. X    svf_draw_symbol(ftbp, w);
  2595. X}
  2596. X
  2597. X/* draw the symbol used for the object described by ftbp into the
  2598. X * DrawingArea widget daw.
  2599. X */
  2600. Xstatic void
  2601. Xsvf_draw_symbol(ftbp, daw)
  2602. XFilterTB *ftbp;
  2603. XWidget daw;
  2604. X{
  2605. X    static GC gc;
  2606. X    Display *dsp = XtDisplay(daw);
  2607. X    Window win = XtWindow(daw);
  2608. X    Obj obj;
  2609. X    Dimension w, h;
  2610. X    int diam;
  2611. X
  2612. X    obj.type = ftbp->type;
  2613. X    if (ftbp->type == FIXED)
  2614. X        obj.f_class = ftbp->class;
  2615. X
  2616. X    get_something (daw, XmNwidth, (char *)&w);
  2617. X    get_something (daw, XmNheight, (char *)&h);
  2618. X    diam = (w > h ? h : w) - 2;
  2619. X
  2620. X    if (!gc) {
  2621. X        XGCValues gcv;
  2622. X        unsigned gcm;
  2623. X        Pixel p;
  2624. X
  2625. X        gcm = GCForeground;
  2626. X        get_something (daw, XmNforeground, (char *)&p);
  2627. X        gcv.foreground = p;
  2628. X        gc = XCreateGC (dsp, win, gcm, &gcv);
  2629. X    }
  2630. X
  2631. X    /* use diam-2 to allow for a little overflow on some symbols */
  2632. X    sv_draw_obj (dsp, win, gc, &obj, (int)w/2, (int)h/2, diam-2, 0);
  2633. X    sv_draw_obj (dsp, win, gc, NULL, 0, 0, 0, 0);    /* flush */
  2634. X}
  2635. X
  2636. X/* called when Apply is pushed on the filter dialog */
  2637. X/* ARGSUSED */
  2638. Xstatic void
  2639. Xsvf_apply_cb (w, client, call)
  2640. XWidget w;
  2641. XXtPointer client;
  2642. XXtPointer call;
  2643. X{
  2644. X    svf_apply();
  2645. X    sv_all(mm_get_now(), 1);
  2646. X}
  2647. X
  2648. X/* called when Ok is pushed on the filter dialog */
  2649. X/* ARGSUSED */
  2650. Xstatic void
  2651. Xsvf_ok_cb (w, client, call)
  2652. XWidget w;
  2653. XXtPointer client;
  2654. XXtPointer call;
  2655. X{
  2656. X    svf_apply();
  2657. X    sv_all(mm_get_now(), 1);
  2658. X    XtUnmanageChild (filter_w);
  2659. X}
  2660. X
  2661. X/* called when Close is pushed on the filter dialog */
  2662. X/* ARGSUSED */
  2663. Xstatic void
  2664. Xsvf_close_cb (w, client, call)
  2665. XWidget w;
  2666. XXtPointer client;
  2667. XXtPointer call;
  2668. X{
  2669. X    XtUnmanageChild (filter_w);
  2670. X}
  2671. X
  2672. X/* called when Toggle is pushed on the filter dialog */
  2673. X/* ARGSUSED */
  2674. Xstatic void
  2675. Xsvf_toggle_cb (w, client, call)
  2676. XWidget w;
  2677. XXtPointer client;
  2678. XXtPointer call;
  2679. X{
  2680. X    int i, j;
  2681. X
  2682. X    for (i = 0; i < XtNumber(filters); i++) {
  2683. X        FilterCat *fcp = &filters[i];
  2684. X        for (j = 0; j < fcp->nftb; j++) {
  2685. X        FilterTB *ftbp = &fcp->ftb[j];
  2686. X        XmToggleButtonSetState (ftbp->tbw, 
  2687. X            !XmToggleButtonGetState(ftbp->tbw), True);
  2688. X        }
  2689. X    }
  2690. X}
  2691. X
  2692. X/* called when All is pushed on the filter dialog */
  2693. X/* ARGSUSED */
  2694. Xstatic void
  2695. Xsvf_all_cb (w, client, call)
  2696. XWidget w;
  2697. XXtPointer client;
  2698. XXtPointer call;
  2699. X{
  2700. X    int i, j;
  2701. X
  2702. X    for (i = 0; i < XtNumber(filters); i++) {
  2703. X        FilterCat *fcp = &filters[i];
  2704. X        for (j = 0; j < fcp->nftb; j++) {
  2705. X        FilterTB *ftbp = &fcp->ftb[j];
  2706. X        XmToggleButtonSetState (ftbp->tbw, True, True);
  2707. X        }
  2708. X    }
  2709. X}
  2710. X
  2711. X/* called when Reset is pushed on the filter dialog */
  2712. X/* ARGSUSED */
  2713. Xstatic void
  2714. Xsvf_reset_cb (w, client, call)
  2715. XWidget w;
  2716. XXtPointer client;
  2717. XXtPointer call;
  2718. X{
  2719. X    svf_reset();
  2720. X}
  2721. X
  2722. X/* called when the "Toggle" button is activated on a particular category.
  2723. X * client is the FilterCat pointer.
  2724. X */
  2725. X/* ARGSUSED */
  2726. Xstatic void
  2727. Xsvf_cat_toggle_cb (w, client, call)
  2728. XWidget w;
  2729. XXtPointer client;
  2730. XXtPointer call;
  2731. X{
  2732. X    FilterCat *fcp = (FilterCat *) client;
  2733. X    int i;
  2734. X
  2735. X    for (i = 0; i < fcp->nftb; i++) {
  2736. X        FilterTB *ftbp = &fcp->ftb[i];
  2737. X        XmToggleButtonSetState (ftbp->tbw, 
  2738. X        !XmToggleButtonGetState(ftbp->tbw), True);
  2739. X    }
  2740. X}
  2741. END_OF_FILE
  2742.   if test 16767 -ne `wc -c <'skyfiltmenu.c'`; then
  2743.     echo shar: \"'skyfiltmenu.c'\" unpacked with wrong size!
  2744.   fi
  2745.   # end of 'skyfiltmenu.c'
  2746. fi
  2747. echo shar: End of archive 19 \(of 21\).
  2748. cp /dev/null ark19isdone
  2749. MISSING=""
  2750. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  2751.     if test ! -f ark${I}isdone ; then
  2752.     MISSING="${MISSING} ${I}"
  2753.     fi
  2754. done
  2755. if test "${MISSING}" = "" ; then
  2756.     echo You have unpacked all 21 archives.
  2757.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2758.     echo Building ephem.db
  2759.     cat > ephem.db.Z.uu ephem.db.Z.uu.?
  2760.     uudecode ephem.db.Z.uu
  2761.     rm ephem.db.Z.uu ephem.db.Z.uu.?
  2762.     uncompress ephem.db.Z
  2763.     echo Building skyviewmenu.c
  2764.     cat > skyviewmenu.c skyviewmenu.c.?
  2765.     rm skyviewmenu.c.?
  2766.     echo Building smallfm.xbm
  2767.     cat > smallfm.xbm smallfm.xbm.?
  2768.     rm smallfm.xbm.?
  2769. else
  2770.     echo You still must unpack the following archives:
  2771.     echo "        " ${MISSING}
  2772. fi
  2773. exit 0
  2774. exit 0 # Just in case...
  2775. -- 
  2776.   // chris@IMD.Sterling.COM            | Send comp.sources.x submissions to:
  2777. \X/  Amiga - The only way to fly!      |
  2778.  "It's intuitively obvious to the most |    sources-x@imd.sterling.com
  2779.   casual observer..."                  |
  2780.