Ignore:
Timestamp:
Jun 15, 2004, 6:54:12 PM (21 years ago)
Author:
cmv
Message:

nouvelle version de xephem/libastro (3.6) cmv 15/6/04

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaExt/XephemAstroLib/dbfmt.c

    r1719 r2551  
    44#include <ctype.h>
    55#include <math.h>
    6 
    7 #if defined(__STDC__)
    86#include <stdlib.h>
    97#include <string.h>
    10 #endif
    11 
    12 #include "P_.h"
     8
    139#include "astro.h"
    14 #include "circum.h"
    1510#include "preferences.h"
    1611
    17 extern void zero_mem P_((void *loc, unsigned len));
    18 extern double atod P_((char *buf));
    19 
    20 int get_fields P_((char *s, int delim, char *fields[]));
    21 int db_set_field P_((char bp[], int id, PrefDateFormat pref, Obj *op));
    22 int db_chk_planet P_((char name[], Obj *op));
     12
     13int get_fields (char *s, int delim, char *fields[]);
    2314
    2415#define MAXDBLINE       256     /* longest allowed db line */
     
    2819#define MAXFLDS 20              /* must be more than on any expected line */
    2920
    30 #define ASIZ(a) (sizeof(a)/sizeof(a[0]))
    31 
    32 static int line_candidate P_((char *buf));
    33 static void crack_year P_((char *bp, PrefDateFormat pref, double *p));
    34 static int db_get_field P_((Obj *op, int id, char *bp));
    35 static int tle_sum P_((char *l));
    36 static double tle_fld P_((char *l, int from, int thru));
    37 static double tle_expfld P_((char *l, int start));
     21static char *enm (char *flds[MAXFLDS]);
     22static int crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     23static int crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     24static int crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     25static int crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     26static int crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     27static int crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     28static int crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
     29static int crack_name (Obj *op, char *flds[MAXFLDS], int nf,
     30    char nm[][MAXNM], int nnm);
     31static void crack_year (char *bp, double *p);
     32static void crack_okdates (char *fld, float *startok, float *endok);
     33static int get_okdates (char *lp, float *sp, float *ep);
     34static int tle_sum (char *l);
     35static double tle_fld (char *l, int from, int thru);
     36static double tle_expfld (char *l, int start);
     37static void write_f (Obj *op, char lp[]);
     38static void write_e (Obj *op, char lp[]);
     39static void write_h (Obj *op, char lp[]);
     40static void write_p (Obj *op, char lp[]);
     41static void write_E (Obj *op, char lp[]);
     42static void write_P (Obj *op, char lp[]);
     43static void write_B (Obj *op, char lp[]);
    3844
    3945/* crack the given .edb database line into op.
    4046 * if ok
    41  *   return 0
     47 *   return number of names in nm[], or 1 if nm == NULL
    4248 * else
    4349 *   if whynot
     
    4753 *       fill whynot with reason message.
    4854 *   return -1
     55 * only the first name is stored in op, all names (up to nnm) are in nm[], or
     56 *   ignored if nm == NULL.
    4957 */
    5058int
    51 db_crack_line (s, op, whynot)
    52 char s[];
    53 Obj *op;
    54 char whynot[];
    55 {
     59db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[])
     60{
     61        char copy[MAXDBLINE];   /* work copy; leave s untouched */
    5662        char *flds[MAXFLDS];    /* point to each field for easy reference */
    57         char *sflds[MAXFLDS];   /* point to each sub field for easy reference */
    58         char copy[MAXDBLINE];   /* work copy; leave s untouched */
    59         int nf, nsf;            /* number of fields and subfields */
     63        int nf;
    6064        int i;
    6165
     66        /* init no response */
     67        if (whynot)
     68            whynot[0] = '\0';
     69
    6270        /* basic initial check */
    63         if (line_candidate (s) < 0) {
    64             if (whynot)
    65                 whynot[0] = '\0';
    66             return (-1);
    67         }
     71        if (dbline_candidate (s) < 0)
     72            return (-1);
    6873
    6974        /* do all the parsing on a copy */
     
    7984        if (nf < 2) {
    8085            if (whynot)
    81                 sprintf (whynot, "Found only %d fields", nf);
     86                sprintf (whynot, "Bogus: %s", s);
    8287            return (-1);
    8388        }
     
    8590        /* switch out on type of object - the second field */
    8691        switch (flds[1][0]) {
    87         case 'f': {
    88             static int ids[] = {F_RA, F_DEC, F_MAG};
    89             if (nf < 5 || nf > 7) {
    90                 if (whynot)
    91                     sprintf (whynot, "f needs 5-7 fields: %d", nf);
    92                 return (-1);
    93             }
    94             zero_mem ((void *)op, sizeof(ObjF));
    95             op->o_type = FIXED;
    96             nsf = get_fields(flds[1], SUBFLD, sflds);
    97             if (nsf > 1 && db_set_field (sflds[1], F_CLASS, PREF_MDY, op) < 0) {
    98                 if (whynot)
    99                     sprintf (whynot, "Bad f class: %c", sflds[1][0]);
    100                 return (-1);
    101             }
    102             if (nsf > 2)
    103                 (void) db_set_field (sflds[2], F_SPECT, PREF_MDY, op);
    104             for (i = 2; i < ASIZ(ids)+2; i++)
    105                 (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
    106             (void) db_set_field (nf>5 && flds[5][0] ? flds[5] : "2000",
    107                                                         F_EPOCH, PREF_MDY, op);
    108             if (nf == 7)
    109                 (void) db_set_field (flds[6], F_SIZE, PREF_MDY, op);
    110             break;
    111         }
    112 
    113         case 'e': {
    114             static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
    115                                                 E_CEPOCH, E_EPOCH, E_M1, E_M2
    116             };
    117             if (nf != 13 && nf != 14) {
    118                 if (whynot)
    119                     sprintf (whynot, "e needs 13 or 14 fields: %d", nf);
    120                 return (-1);
    121             }
    122             zero_mem ((void *)op, sizeof(ObjE));
    123             op->o_type = ELLIPTICAL;
    124             for (i = 2; i < ASIZ(ids)+2; i++)
    125                 (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
    126             if (nf == 14)
    127                 (void) db_set_field (flds[13], E_SIZE, PREF_MDY, op);
    128             break;
    129         }
    130 
    131         case 'h': {
    132             static int ids[]= {H_EP,H_INC,H_LAN,H_AOP,H_E,H_QP,H_EPOCH,H_G,H_K};
    133             if (nf != 11 && nf != 12) {
    134                 if (whynot)
    135                     sprintf (whynot, "h needs 11 or 12 fields: %d", nf);
    136                 return (-1);
    137             }
    138             zero_mem ((void *)op, sizeof(ObjH));
    139             op->o_type = HYPERBOLIC;
    140             for (i = 2; i < ASIZ(ids)+2; i++)
    141                 (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
    142             if (nf == 12)
    143                 (void) db_set_field (flds[11], H_SIZE, PREF_MDY, op);
    144             break;
    145         }
    146 
    147         case 'p': {
    148             static int ids[] = {P_EP,P_INC,P_AOP,P_QP,P_LAN,P_EPOCH,P_G,P_K};
    149             if (nf != 10 && nf != 11) {
    150                 if (whynot)
    151                     sprintf (whynot, "p needs 10 or 11 fields: %d", nf);
    152                 return (-1);
    153             }
    154             zero_mem ((void *)op, sizeof(ObjP));
    155             op->o_type = PARABOLIC;
    156             for (i = 2; i < ASIZ(ids)+2; i++)
    157                 (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
    158             if (nf == 11)
    159                 (void) db_set_field (flds[10], P_SIZE, PREF_MDY, op);
    160             break;
    161         }
    162 
    163         case 'E': {
    164             static int ids[] = {ES_EPOCH,ES_INC,ES_RAAN,ES_E,ES_AP,ES_M,ES_N,
    165                                                             ES_DECAY,ES_ORBIT};
    166             if (nf != 11 && nf != 12) {
    167                 if (whynot)
    168                     sprintf (whynot, "E needs 11 or 12 fields: %d", nf);
    169                 return (-1);
    170             }
    171             zero_mem ((void *)op, sizeof(ObjES));
    172             op->o_type = EARTHSAT;
    173             for (i = 2; i < ASIZ(ids)+2; i++)
    174                 (void) db_set_field (flds[i], ids[i-2], PREF_MDY, op);
    175             if (nf == 12)
    176                 (void) db_set_field (flds[11], ES_DRAG, PREF_MDY, op);
    177             break;
    178         }
     92
     93        case 'f':
     94            if (crack_f (op, flds, nf, whynot) < 0)
     95                return (-1);
     96            break;
     97
     98        case 'e':
     99            if (crack_e (op, flds, nf, whynot) < 0)
     100                return (-1);
     101            break;
     102
     103        case 'h':
     104            if (crack_h (op, flds, nf, whynot) < 0)
     105                return (-1);
     106            break;
     107
     108        case 'p':
     109            if (crack_p (op, flds, nf, whynot) < 0)
     110                return (-1);
     111            break;
     112
     113        case 'B':
     114            if (crack_B (op, flds, nf, whynot) < 0)
     115                return (-1);
     116            break;
     117
     118        case 'E':
     119            if (crack_E (op, flds, nf, whynot) < 0)
     120                return (-1);
     121            break;
    179122
    180123        case 'P':
    181             /* allow, though ignore, anything after the P */
    182             i = db_chk_planet (flds[0], op);    /* does o_name too */
    183             if (i < 0) {
    184                 if (whynot)
    185                     sprintf (whynot, "Bad planet: %s", flds[0]);
    186             }
    187             return (i);
     124            if (crack_P (op, flds, nf, whynot) < 0)
     125                return (-1);
     126            break;
    188127
    189128        default:
    190129            if (whynot)
    191                 sprintf (whynot, "Unknown type: %c", flds[1][0]);
    192             return (-1);
    193         }
    194 
    195         /* load up o_name */
    196         (void) db_set_field (flds[0], O_NAME, PREF_MDY, op);
    197 
    198         return (0);
    199 }
    200 
    201 /* return 0 if TLE checksum is ok, else -1 */
    202 static int
    203 tle_sum (l)
    204 char *l;
    205 {
    206         char *lastl = l + 68;
    207         int sum;
    208 
    209         for (sum = 0; l < lastl; ) {
    210             char c = *l++;
    211             if (c == '\0')
    212                 return (-1);
    213             if (isdigit(c))
    214                 sum += c - '0';
    215             else if (c == '-')
    216                 sum++;
    217         }
    218 
    219         return (*l - '0' == (sum%10) ? 0 : -1);
    220 }
    221 
    222 /* extract the given columns and return value.
    223  * N.B. from and to are 1-based within l
     130                sprintf (whynot, "%s: Unknown type %c for %s", enm(flds),
     131                                                        flds[1][0], flds[0]);
     132            return (-1);
     133        }
     134
     135        return (crack_name (op, flds, nf, nm, nnm));
     136}
     137
     138/* write the given Obj in .edb format to lp[].
     139 * we do _not_ include a trailing '\n'.
    224140 */
    225 static double
    226 tle_fld (l, from, thru)
    227 char *l;
    228 int from, thru;
    229 {
    230         char buf[32];
    231 
    232         sprintf (buf, "%.*s", thru-from+1, l+from-1);
    233         return (atod (buf));
    234 }
    235 
    236 /* extract the exponential value starting at the given column.
    237  * N.B. start is 1-based within l
    238  */
    239 static double
    240 tle_expfld (l, start)
    241 char *l;
    242 int start;
    243 {
    244         char buf[32];
    245         double v;
    246 
    247         sprintf (buf, ".%.*s", 5, l+start);
    248         v = atod (buf) * pow (10.0, tle_fld(l, start+6, start+7));
    249         if (l[start-1] == '-')
    250             v = -v;
    251         return (v);
     141void
     142db_write_line (Obj *op, char lp[])
     143{
     144        int priorpref;
     145
     146        /* .edb format always uses MDY.
     147         * N.B. must restore old value before returning from here!
     148         */
     149        priorpref = pref_set (PREF_DATE_FORMAT, PREF_MDY);
     150
     151        switch (op->o_type) {
     152        case FIXED:
     153            write_f (op, lp);
     154            break;
     155
     156        case BINARYSTAR:
     157            write_B (op, lp);
     158            break;
     159
     160        case ELLIPTICAL:
     161            write_e (op, lp);
     162            break;
     163
     164        case HYPERBOLIC:
     165            write_h (op, lp);
     166            break;
     167
     168        case PARABOLIC:
     169            write_p (op, lp);
     170            break;
     171
     172        case EARTHSAT:
     173            write_E (op, lp);
     174            break;
     175
     176        case PLANET:
     177            write_P (op, lp);
     178            break;
     179
     180        default:
     181            printf ("Unknown type for %s: %d\n", op->o_name, op->o_type);
     182            abort();
     183        }
     184
     185        /* restore date format preference */
     186        (void) pref_set (PREF_DATE_FORMAT, priorpref);
    252187}
    253188
     
    261196 */
    262197int
    263 db_tle (name, l1, l2, op)
    264 char *name, *l1, *l2;
    265 Obj *op;
     198db_tle (char *name, char *l1, char *l2, Obj *op)
    266199{
    267200        double ep;
     
    306239        /* goodies from "line 1" */
    307240        op->es_drag = (float) tle_expfld (l1, 54);
     241        op->es_decay = (float) tle_fld (l1, 34, 43);
    308242        i = (int) tle_fld (l1, 19, 20);
    309243        if (i < 57)
     
    325259}
    326260
    327 /* write the given Obj in .edb format to lp[].
    328  * we do _not_ include a trailing '\n'.
    329  */
    330 void
    331 db_write_line (op, lp)
    332 Obj *op;
    333 char *lp;
    334 {
    335         int priorpref;
    336         int i;
    337 
    338         /* .edb format always uses MDY.
    339          * N.B. must restore old value before returning from here!
    340          */
    341         priorpref = pref_set (PREF_DATE_FORMAT, PREF_MDY);
    342 
    343         switch (op->o_type) {
    344         case FIXED: {
    345             static int ids[] = {F_CLASS, F_SPECT, F_RA, F_DEC, F_MAG, F_EPOCH,
    346                 F_SIZE
    347             };
    348 
    349             sprintf (lp, "%s,f", op->o_name);
    350             lp += strlen(lp);
    351             for (i = 0; i < ASIZ(ids); i++)
    352                 lp += db_get_field (op, ids[i], lp);
    353             break;
    354             }
    355 
    356         case ELLIPTICAL: {
    357             static int ids[] = {E_INC, E_LAN, E_AOP, E_A, E_N, E_E, E_M,
    358                                         E_CEPOCH, E_EPOCH, E_M1, E_M2, E_SIZE
    359             };
    360 
    361             sprintf (lp, "%s,e", op->o_name);
    362             lp += strlen(lp);
    363             for (i = 0; i < ASIZ(ids); i++)
    364                 lp += db_get_field (op, ids[i], lp);
    365             break;
    366             }
    367 
    368         case HYPERBOLIC: {
    369             static int ids[]= {H_EP, H_INC, H_LAN, H_AOP, H_E, H_QP, H_EPOCH,
    370                 H_G, H_K, H_SIZE
    371             };
    372 
    373             sprintf (lp, "%s,h", op->o_name);
    374             lp += strlen(lp);
    375             for (i = 0; i < ASIZ(ids); i++)
    376                 lp += db_get_field (op, ids[i], lp);
    377             break;
    378             }
    379 
    380         case PARABOLIC: {
    381             static int ids[] = {P_EP, P_INC, P_AOP, P_QP, P_LAN, P_EPOCH, P_G,
    382                 P_K, P_SIZE
    383             };
    384 
    385             sprintf (lp, "%s,p", op->o_name);
    386             lp += strlen(lp);
    387             for (i = 0; i < ASIZ(ids); i++)
    388                 lp += db_get_field (op, ids[i], lp);
    389             break;
    390             }
    391 
    392         case EARTHSAT: {
    393             static int ids[] = {ES_EPOCH, ES_INC, ES_RAAN, ES_E, ES_AP, ES_M,
    394                 ES_N, ES_DECAY,ES_ORBIT,ES_DRAG
    395             };
    396 
    397             sprintf (lp, "%s,E", op->o_name);
    398             lp += strlen(lp);
    399             for (i = 0; i < ASIZ(ids); i++)
    400                 lp += db_get_field (op, ids[i], lp);
    401             break;
    402             }
    403 
    404         case PLANET:
    405             sprintf (lp, "%s,P", op->o_name);
    406             lp += strlen(lp);
    407             break;
    408 
    409         default:
    410             printf ("Unknown type for %s: %d\n", op->o_name, op->o_type);
    411             exit(1);
    412         }
    413 
    414         /* restore date format preference */
    415         (void) pref_set (PREF_DATE_FORMAT, priorpref);
    416 }
    417 
    418 /* given a text buffer and a field id, and a PREF_DATE_FORMAT,
    419  *   set the corresponding member in *op.
    420  * return 0 if ok, else -1.
     261/* return 0 if op has no date range information or what it does have brackets
     262 * now, else -1
    421263 */
    422264int
    423 db_set_field (bp, id, pref, op)
    424 char bp[];
    425 int id;
    426 PrefDateFormat pref;
    427 Obj *op;
    428 {
    429         double tmp;
    430 
    431         /* include all the enums and in numeric order to give us the best
    432          * possible chance the compiler will implement this as a jump table.
    433          */
    434         switch (id) {
    435         case O_TYPE:
    436             printf ("db_set_field: called with id==O_TYPE\n");
    437             exit(1);
    438             break;
    439         case O_NAME:
    440             (void) strncpy (op->o_name, bp, sizeof(op->o_name)-1);
    441             op->o_name[sizeof(op->o_name)-1] = '\0';
    442             break;
    443         case F_RA:
    444             f_scansex (radhr(op->f_RA), bp, &tmp);
    445             op->f_RA = (float) hrrad(tmp);
    446             break;
    447         case F_DEC:
    448             f_scansex (raddeg(op->f_dec), bp, &tmp);
    449             op->f_dec = (float) degrad(tmp);
    450             break;
    451         case F_EPOCH:
    452             tmp = op->f_epoch;
    453             crack_year (bp, pref, &tmp);
    454             op->f_epoch = (float) tmp;
    455             break;
    456         case F_MAG:
    457             set_fmag (op, atod(bp));
    458             break;
    459         case F_SIZE:
    460             op->f_size = (float) atod(bp);
    461             {
    462                 /* optional minor axis and position angle subfields */
    463                 char *sflds[MAXFLDS];
    464                 int nsf = get_fields(bp, SUBFLD, sflds);
    465 
    466                 if (nsf == 3) {
    467                     set_ratio(op, op->s_size, atod(sflds[1]));
    468                     set_pa(op,degrad(atod(sflds[2])));
    469                 } else {
    470                     set_ratio(op,1,1);  /* round */
    471                     set_pa(op,0.0);
    472                 }
    473             }
    474             break;
    475         case F_CLASS:
    476             switch (bp[0]) {
    477             case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
    478             case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
    479             case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
    480             case 'U': case 'V':
    481                 op->f_class = bp[0];
    482                 break;
    483             default:
    484                 return (-1);
    485             }
    486             break;
    487         case F_SPECT: {
    488             int i, j;
    489             /* fill f_spect all the way */
    490             for (i = j = 0; i < sizeof(op->f_spect); i++)
    491                 if ((op->f_spect[i] = bp[j]) != 0)
    492                     j++;
    493             break;
    494         }
    495 
    496         case E_INC:
    497             op->e_inc = (float) atod (bp);
    498             break;
    499         case E_LAN:
    500             op->e_Om = (float) atod (bp);
    501             break;
    502         case E_AOP:
    503             op->e_om = (float) atod (bp);
    504             break;
    505         case E_A:
    506             op->e_a = (float) atod (bp);
    507             break;
    508         case E_N:
    509             /* retired */
    510             break;
    511         case E_E:
    512             op->e_e = atod (bp);
    513             break;
    514         case E_M:
    515             op->e_M = (float) atod (bp);
    516             break;
    517         case E_CEPOCH:
    518             crack_year (bp, pref, &op->e_cepoch);
    519             break;
    520         case E_EPOCH:
    521             crack_year (bp, pref, &op->e_epoch);
    522             break;
    523         case E_M1:
    524             switch (bp[0]) {
    525             case 'g':
    526                 op->e_mag.whichm = MAG_gk;
    527                 bp++;
    528                 break;
    529             case 'H':
    530                 op->e_mag.whichm = MAG_HG;
    531                 bp++;
    532                 break;
    533             default:
    534                 /* leave type unchanged if no or unrecognized prefix */
    535                 break;
    536             }
    537             op->e_mag.m1 = (float) atod(bp);
    538             break;
    539         case E_M2:
    540             switch (bp[0]) {
    541             case 'k':
    542                 op->e_mag.whichm = MAG_gk;
    543                 bp++;
    544                 break;
    545             case 'G':
    546                 op->e_mag.whichm = MAG_HG;
    547                 bp++;
    548                 break;
    549             default:
    550                 /* leave type unchanged if no or unrecognized prefix */
    551                 break;
    552             }
    553             op->e_mag.m2 = (float) atod(bp);
    554             break;
    555         case E_SIZE:
    556             op->e_size = (float) atod (bp);
    557             break;
    558 
    559         case H_EP:
    560             crack_year (bp, pref, &op->h_ep);
    561             break;
    562         case H_INC:
    563             op->h_inc = (float) atod (bp);
    564             break;
    565         case H_LAN:
    566             op->h_Om = (float) atod (bp);
    567             break;
    568         case H_AOP:
    569             op->h_om = (float) atod (bp);
    570             break;
    571         case H_E:
    572             op->h_e = (float) atod (bp);
    573             break;
    574         case H_QP:
    575             op->h_qp = (float) atod (bp);
    576             break;
    577         case H_EPOCH:
    578             crack_year (bp, pref, &op->h_epoch);
    579             break;
    580         case H_G:
    581             op->h_g = (float) atod (bp);
    582             break;
    583         case H_K:
    584             op->h_k = (float) atod (bp);
    585             break;
    586         case H_SIZE:
    587             op->h_size = (float) atod (bp);
    588             break;
    589 
    590         case P_EP:
    591             crack_year (bp, pref, &op->p_ep);
    592             break;
    593         case P_INC:
    594             op->p_inc = (float) atod (bp);
    595             break;
    596         case P_AOP:
    597             op->p_om = (float) atod (bp);
    598             break;
    599         case P_QP:
    600             op->p_qp = (float) atod (bp);
    601             break;
    602         case P_LAN:
    603             op->p_Om = (float) atod (bp);
    604             break;
    605         case P_EPOCH:
    606             crack_year (bp, pref, &op->p_epoch);
    607             break;
    608         case P_G:
    609             op->p_g = (float) atod (bp);
    610             break;
    611         case P_K:
    612             op->p_k = (float) atod (bp);
    613             break;
    614         case P_SIZE:
    615             op->p_size = (float) atod (bp);
    616             break;
    617 
    618         case ES_EPOCH:
    619             crack_year (bp, pref, &op->es_epoch);
    620             break;
    621         case ES_INC:
    622             op->es_inc = (float) atod (bp);
    623             break;
    624         case ES_RAAN:
    625             op->es_raan = (float) atod (bp);
    626             break;
    627         case ES_E:
    628             op->es_e = (float) atod (bp);
    629             break;
    630         case ES_AP:
    631             op->es_ap = (float) atod (bp);
    632             break;
    633         case ES_M:
    634             op->es_M = (float) atod (bp);
    635             break;
    636         case ES_N:
    637             op->es_n = atod (bp);
    638             break;
    639         case ES_DECAY:
    640             op->es_decay = (float) atod (bp);
    641             break;
    642         case ES_ORBIT:
    643             op->es_orbit = atoi (bp);
    644             break;
    645         case ES_DRAG:
    646             op->es_drag = (float) atod (bp);
    647             break;
    648 
     265dateRangeOK (Now *np, Obj *op)
     266{
     267        float *sp, *ep;
     268
     269        switch (op->o_type) {
     270        case ELLIPTICAL:
     271            sp = &op->e_startok;
     272            ep = &op->e_endok;
     273            break;
     274        case HYPERBOLIC:
     275            sp = &op->h_startok;
     276            ep = &op->h_endok;
     277            break;
     278        case PARABOLIC:
     279            sp = &op->p_startok;
     280            ep = &op->p_endok;
     281            break;
     282        case EARTHSAT:
     283            sp = &op->es_startok;
     284            ep = &op->es_endok;
     285            break;
    649286        default:
    650             printf ("BUG! db_set_field: bad id: %d\n", id);
    651             exit (1);
    652         }
    653 
    654         return (0);
     287            return (0);
     288        }
     289
     290        if (*sp <= mjd && (!*ep || mjd <= *ep))
     291            return (0);
     292        return (-1);
    655293}
    656294
     
    662300 */
    663301int
    664 get_fields (s, delim, fields)
    665 char *s;
    666 int delim;
    667 char *fields[];
     302get_fields (char *s, int delim, char *fields[])
    668303{
    669304        int n;
     
    684319}
    685320
    686 /* check name for being a planet.
    687  * if so, fill in *op and return 0, else return -1.
    688  */
    689 int
    690 db_chk_planet (name, op)
    691 char name[];
    692 Obj *op;
    693 {
    694         char namecpy[256];
    695         int i;
    696 
    697         /* these must match the order in astro.h */
    698         static char *planet_names[] = {
    699             "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
    700             "Uranus", "Neptune", "Pluto", "Sun", "Moon",
    701         };
    702 
    703         /* make a copy to match our case -- strcasecmp() not entirely portable*/
    704         strcpy (namecpy, name);
    705         if (islower(namecpy[0]))
    706             namecpy[0] = toupper(namecpy[0]);
    707         for (i = 1; namecpy[i]; i++)
    708             if (isupper(namecpy[i]))
    709                 namecpy[i] = tolower(namecpy[i]);
    710 
    711         for (i = MERCURY; i <= MOON; i++) {
    712             if (strcmp (namecpy, planet_names[i]) == 0) {
    713                 zero_mem ((void *)op, sizeof(ObjPl));
    714                 op->o_type = PLANET;
    715                 (void) strcpy (op->o_name, planet_names[i]);
    716                 op->pl.pl_code = i;
    717                 return (0);
    718             }
    719         }
    720 
    721         return (-1);
    722 }
    723 
    724321/* return 0 if buf qualifies as a database line worthy of a cracking
    725322 * attempt, else -1.
    726323 */
     324int
     325dbline_candidate (char *buf)
     326{
     327        char c = buf[0];
     328
     329        return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
     330}
     331
     332/* return 0 if TLE checksum is ok, else -1 */
    727333static int
    728 line_candidate (buf)
    729 char *buf;
    730 {
    731         char c = buf[0];
    732 
    733         return (c == '#' || c == '!' || isspace(c) ? -1 : 0);
    734 }
    735 
    736 /* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x)
    737  * and a DateFormat preference convert it to an mjd and store it at *p.
     334tle_sum (char *l)
     335{
     336        char *lastl = l + 68;
     337        int sum;
     338
     339        for (sum = 0; l < lastl; ) {
     340            char c = *l++;
     341            if (c == '\0')
     342                return (-1);
     343            if (isdigit(c))
     344                sum += c - '0';
     345            else if (c == '-')
     346                sum++;
     347        }
     348
     349        return (*l - '0' == (sum%10) ? 0 : -1);
     350}
     351
     352/* extract the given columns and return value.
     353 * N.B. from and to are 1-based within l
     354 */
     355static double
     356tle_fld (char *l, int from, int thru)
     357{
     358        char buf[32];
     359
     360        sprintf (buf, "%.*s", thru-from+1, l+from-1);
     361        return (atod (buf));
     362}
     363
     364/* extract the exponential value starting at the given column.
     365 * N.B. start is 1-based within l
     366 */
     367static double
     368tle_expfld (char *l, int start)
     369{
     370        char buf[32];
     371        double v;
     372
     373        sprintf (buf, ".%.*s", 5, l+start);
     374        v = atod (buf) * pow (10.0, tle_fld(l, start+6, start+7));
     375        if (l[start-1] == '-')
     376            v = -v;
     377        return (v);
     378}
     379
     380static int
     381crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     382{
     383        char *sflds[MAXFLDS];
     384        double tmp;
     385        int nsf;
     386
     387        if (nf < 5 || nf > 7) {
     388            if (whynot)
     389                sprintf (whynot, "%s: f needs 5-7 fields, not %d",enm(flds),nf);
     390            return (-1);
     391        }
     392
     393        zero_mem ((void *)op, sizeof(ObjF));
     394        op->o_type = FIXED;
     395
     396        nsf = get_fields(flds[1], SUBFLD, sflds);
     397        if (nsf > 1) {
     398            switch (sflds[1][0]) {
     399            case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
     400            case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
     401            case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
     402            case 'U': case 'V': case 'Y':
     403                op->f_class = sflds[1][0];
     404                if (op->f_class == 'B')
     405                    op->f_class = 'D';  /* merge B and D since BINARYSTAR */
     406                break;
     407            default:
     408                if (whynot)
     409                    sprintf (whynot, "%s: Bad f class: %c", enm(flds),
     410                                                                sflds[1][0]);
     411                return (-1);
     412            }
     413        }
     414        if (nsf > 2) {
     415            /* fill f_spect all the way */
     416            char buf[sizeof(op->f_spect)+1];
     417            memset (buf, 0, sizeof(buf));
     418            sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
     419            memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
     420        }
     421
     422        nsf = get_fields(flds[2], SUBFLD, sflds);
     423        f_scansexa (sflds[0], &tmp);
     424        op->f_RA = (float) hrrad(tmp);
     425        if (nsf > 1)
     426            op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
     427
     428        nsf = get_fields(flds[3], SUBFLD, sflds);
     429        f_scansexa (sflds[0], &tmp);
     430        op->f_dec = (float) degrad(tmp);
     431        if (nsf > 1)
     432            op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
     433        if (fabs(op->f_dec) < PI/2)
     434            op->f_pmRA /= cos (op->f_dec);
     435
     436        set_fmag (op, atod(flds[4]));
     437
     438        if (nf > 5 && flds[5][0]) {
     439            tmp = op->f_epoch;
     440            crack_year (flds[5], &tmp);
     441            op->f_epoch = (float) tmp;
     442        } else
     443            op->f_epoch = J2000;        /* default */
     444
     445        if (nf > 6) {
     446            op->f_size = (float) atod(flds[6]);
     447
     448            /* optional minor axis and position angle subfields */
     449            nsf = get_fields(flds[6], SUBFLD, sflds);
     450            if (nsf == 3) {
     451                set_ratio(op, op->s_size, atod(sflds[1]));
     452                set_pa(op,degrad(atod(sflds[2])));
     453            } else {
     454                set_ratio(op,1,1);      /* round */
     455                set_pa(op,0.0);
     456            }
     457        }
     458
     459        return (0);
     460}
     461
     462static int
     463crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     464{
     465        if (nf != 13 && nf != 14) {
     466            if (whynot)
     467                sprintf (whynot, "%s: e needs 13 or 14 fields, not %d",
     468                                                                enm(flds), nf);
     469            return (-1);
     470        }
     471
     472        zero_mem ((void *)op, sizeof(ObjE));
     473        op->o_type = ELLIPTICAL;
     474
     475        op->e_inc = (float) atod (flds[2]);
     476        op->e_Om = (float) atod (flds[3]);
     477        op->e_om = (float) atod (flds[4]);
     478        op->e_a = (float) atod (flds[5]);
     479        /* retired op->e_n = (float) atod (flds[6]); */
     480        op->e_e = atod (flds[7]);
     481        op->e_M = (float) atod (flds[8]);
     482        crack_year (flds[9], &op->e_cepoch);
     483        crack_okdates (flds[9], &op->e_startok, &op->e_endok);
     484        crack_year (flds[10], &op->e_epoch);
     485
     486        /* magnitude model gk or HG(default). allow prefixes in either field */
     487        op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG;
     488        if (isdigit(flds[11][0]))
     489            op->e_mag.m1 = (float) atod(&flds[11][0]);
     490        else
     491            op->e_mag.m1 = (float) atod(&flds[11][1]);
     492        if (isdigit(flds[12][0]))
     493            op->e_mag.m2 = (float) atod(&flds[12][0]);
     494        else
     495            op->e_mag.m2 = (float) atod(&flds[12][1]);
     496
     497        if (nf == 14)
     498            op->e_size = (float) atod (flds[13]);
     499
     500        return (0);
     501}
     502
     503static int
     504crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     505{
     506        if (nf != 11 && nf != 12) {
     507            if (whynot)
     508                sprintf (whynot, "%s: h needs 11 or 12 fields, not %d",
     509                                                                enm(flds), nf);
     510            return (-1);
     511        }
     512
     513        zero_mem ((void *)op, sizeof(ObjH));
     514        op->o_type = HYPERBOLIC;
     515
     516        crack_year (flds[2], &op->h_ep);
     517        crack_okdates (flds[2], &op->h_startok, &op->h_endok);
     518        op->h_inc = (float) atod (flds[3]);
     519        op->h_Om = (float) atod (flds[4]);
     520        op->h_om = (float) atod (flds[5]);
     521        op->h_e = (float) atod (flds[6]);
     522        op->h_qp = (float) atod (flds[7]);
     523        crack_year (flds[8], &op->h_epoch);
     524        op->h_g = (float) atod (flds[9]);
     525        op->h_k = (float) atod (flds[10]);
     526
     527        if (nf == 12)
     528            op->h_size = (float) atod (flds[11]);
     529
     530        return (0);
     531}
     532
     533static int
     534crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     535{
     536        if (nf != 10 && nf != 11) {
     537            if (whynot)
     538                sprintf (whynot, "%s: p needs 10 or 11 fields, not %d",
     539                                                                enm(flds), nf);
     540            return (-1);
     541        }
     542
     543        zero_mem ((void *)op, sizeof(ObjP));
     544        op->o_type = PARABOLIC;
     545
     546        crack_year (flds[2], &op->p_ep);
     547        crack_okdates (flds[2], &op->p_startok, &op->p_endok);
     548        op->p_inc = (float) atod (flds[3]);
     549        op->p_om = (float) atod (flds[4]);
     550        op->p_qp = (float) atod (flds[5]);
     551        op->p_Om = (float) atod (flds[6]);
     552        crack_year (flds[7], &op->p_epoch);
     553        op->p_g = (float) atod (flds[8]);
     554        op->p_k = (float) atod (flds[9]);
     555
     556        if (nf == 11)
     557            op->p_size = (float) atod (flds[10]);
     558
     559        return (0);
     560}
     561
     562static int
     563crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     564{
     565        if (nf != 11 && nf != 12) {
     566            if (whynot)
     567                sprintf (whynot, "%s: E needs 11 or 12 fields, not %d",
     568                                                            enm(flds), nf);
     569            return (-1);
     570        }
     571
     572        zero_mem ((void *)op, sizeof(ObjES));
     573        op->o_type = EARTHSAT;
     574        crack_year (flds[2], &op->es_epoch);
     575        crack_okdates (flds[2], &op->es_startok, &op->es_endok);
     576        op->es_inc = (float) atod (flds[3]);
     577        op->es_raan = (float) atod (flds[4]);
     578        op->es_e = (float) atod (flds[5]);
     579        op->es_ap = (float) atod (flds[6]);
     580        op->es_M = (float) atod (flds[7]);
     581        op->es_n = atod (flds[8]);
     582        op->es_decay = (float) atod (flds[9]);
     583        op->es_orbit = atoi (flds[10]);
     584        if (nf == 12)
     585            op->es_drag = (float) atod (flds[11]);
     586
     587        return (0);
     588}
     589
     590static int
     591crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     592{
     593        Obj *bi;
     594        int nbi;
     595        int i;
     596
     597        nbi = getBuiltInObjs (&bi);
     598
     599        for (i = 0; i < nbi; i++) {
     600            Obj *bop = bi + i;
     601            if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) {
     602                memcpy ((void *)op, bop, sizeof(ObjPl));
     603                return (0);
     604            }
     605        }
     606
     607        if (whynot)
     608            sprintf (whynot, "%s: Unknown planet or moon", enm(flds));
     609        return (-1);
     610}
     611
     612static int
     613crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
     614{
     615        char *sflds[MAXFLDS];
     616        double tmp;
     617        int nsf;
     618
     619        if (nf != 7) {
     620            if (whynot)
     621                sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf);
     622            return (-1);
     623        }
     624
     625        zero_mem ((void *)op, sizeof(ObjB));
     626        op->o_type = BINARYSTAR;
     627
     628        nsf = get_fields(flds[1], SUBFLD, sflds);
     629        if (nsf > 1) {
     630            switch (sflds[1][0]) {
     631            case 'a': case 'c': case 'e': case 'x': case 'y': case 'o':
     632            case 's': case 't': case 'u': case 'v': case 'b': case 'd':
     633            case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y':
     634                op->f_class = sflds[1][0];
     635                break;
     636            default:
     637                if (whynot)
     638                    sprintf (whynot, "%s: Bad B class: %c", enm(flds),
     639                                                                sflds[1][0]);
     640                return (-1);
     641            }
     642        }
     643        if (nsf > 2) {
     644            /* fill f_spect all the way */
     645            char buf[sizeof(op->f_spect)+1];
     646            memset (buf, 0, sizeof(buf));
     647            sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
     648            memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
     649        }
     650        if (nsf > 3) {
     651            /* fill b_2spect all the way */
     652            char buf[sizeof(op->b_2spect)+1];
     653            memset (buf, 0, sizeof(buf));
     654            sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]);
     655            memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect));
     656        }
     657
     658        nsf = get_fields(flds[2], SUBFLD, sflds);
     659        f_scansexa (sflds[0], &tmp);
     660        op->f_RA = (float) hrrad(tmp);
     661        if (nsf > 1)
     662            op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
     663
     664        nsf = get_fields(flds[3], SUBFLD, sflds);
     665        f_scansexa (sflds[0], &tmp);
     666        op->f_dec = (float) degrad(tmp);
     667        if (nsf > 1)
     668            op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
     669        if (fabs(op->f_dec) < PI/2)
     670            op->f_pmRA /= cos (op->f_dec);
     671
     672        nsf = get_fields(flds[4], SUBFLD, sflds);
     673        if (nsf > 0)
     674            set_fmag (op, atod(sflds[0]));
     675        if (nsf > 1)
     676            op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5);
     677
     678        if (flds[5][0]) {
     679            tmp = op->f_epoch;
     680            crack_year (flds[5], &tmp);
     681            op->f_epoch = (float) tmp;
     682        } else
     683            op->f_epoch = J2000;        /* default */
     684
     685        nsf = get_fields(flds[6], SUBFLD, sflds);
     686        if (nsf == 7) {
     687            int l;
     688            char c;
     689
     690            op->b_bo.bo_a = atod(sflds[0]);
     691            op->b_bo.bo_i = atod(sflds[1]);
     692            op->b_bo.bo_O = atod(sflds[2]);
     693            op->b_bo.bo_e = atod(sflds[3]);
     694            op->b_bo.bo_T = atod(sflds[4]);
     695            op->b_bo.bo_o = atod(sflds[5]);
     696            op->b_bo.bo_P = atod(sflds[6]);
     697
     698            /* reject some weird entries actually seen in real lists */
     699            if (op->b_bo.bo_a <= 0) {
     700                if (whynot)
     701                    sprintf (whynot, "%s: Bogus B semi major axis: %g",
     702                                                    enm(flds), op->b_bo.bo_a);
     703                return (-1);
     704            }
     705            if (op->b_bo.bo_P <= 0) {
     706                if (whynot)
     707                    sprintf (whynot, "%s: Bogus B period: %g", enm(flds),
     708                                                                op->b_bo.bo_P);
     709                return (-1);
     710            }
     711
     712            /* scale period */
     713            l = strlen (sflds[6]);
     714            c = sflds[6][l-1];
     715            switch (c) {
     716            case 'y': case 'Y':
     717                break;
     718            case 'h': case 'H':
     719                op->b_bo.bo_P /= (24.0*365.25);
     720                break;
     721            case 'd': case 'D':
     722                op->b_bo.bo_P /= 365.25;
     723                break;
     724            default:
     725                if (c != ' ' && !isdigit(c)) {
     726                    if (whynot)
     727                        sprintf (whynot,"%s: B period suffix not Y, D or H: %c",
     728                                                                enm(flds), c);
     729                    return (-1);
     730                }
     731            }
     732
     733        } else if (nsf==3 || nsf==6 || nsf==9) {
     734            double yr;
     735            int i;
     736
     737            op->b_nbp = nsf/3;
     738            for (i = 0; i < nsf; i += 3) {
     739                tmp = 0;
     740                crack_year (sflds[i+0], &tmp);
     741                mjd_year (tmp, &yr);
     742                op->b_bp[i/3].bp_ep = (float)yr;
     743                op->b_bp[i/3].bp_sep = atod(sflds[i+1]);
     744                op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2]));
     745            }
     746        } else {
     747            if (whynot)
     748                sprintf (whynot,
     749                        "%s: B needs 3,6 or 7 subfields in field 7, not %d",
     750                                                                enm(flds), nsf);
     751            return (-1);
     752        }
     753
     754        return (0);
     755}
     756
     757/* put all names in nm but load only the first into o_name */
     758static int
     759crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm)
     760{
     761        char *sflds[MAXFLDS];
     762        int nsf;
     763        int i;
     764       
     765        nsf = get_fields (flds[0], SUBFLD, sflds);
     766        for (i = 0; nm && i < nsf && i < nnm; i++) {
     767            strncpy (nm[i], sflds[i], MAXNM);
     768            nm[i][MAXNM-1] = '\0';
     769        }
     770        strncpy (op->o_name, sflds[0], MAXNM-1);
     771        return (nsf);
     772}
     773
     774/* simple name cracker just for error messages */
     775static char *
     776enm (char *flds[MAXFLDS])
     777{
     778        char *sflds[MAXFLDS];
     779        int nsf = get_fields (flds[0], SUBFLD, sflds);
     780        return (nsf > 0 ? sflds[0] : "Unknown");
     781}
     782
     783/* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date
     784 * convert it to an mjd and store it at *p.
    738785 */
    739786static void
    740 crack_year (bp, pref, p)
    741 char *bp;
    742 PrefDateFormat pref;
    743 double *p;
     787crack_year (char *bp, double *p)
    744788{
    745789        int m, y;
     
    747791
    748792        mjd_cal (*p, &m, &d, &y);       /* init with current */
    749         f_sscandate (bp, pref, &m, &d, &y);
     793        f_sscandate (bp, PREF_MDY, &m, &d, &y);
    750794        cal_mjd (m, d, y, p);
    751795}
    752796
    753 /* given an *op and a field id, add it to the given text buffer bp.
    754  * return the number of characters added to bp.
     797/* crack the startok and endok date fields found in several Obj types.
     798 * set to 0 if blank or any problems.
     799 */
     800static void
     801crack_okdates (char *fld, float *startok, float *endok)
     802{
     803        char *sflds[MAXFLDS];
     804        double tmp;
     805        int m, y;
     806        double d;
     807        int nsf;
     808
     809        *startok = *endok = 0;
     810        nsf = get_fields(fld, SUBFLD, sflds);
     811        if (nsf > 1) {
     812            d = m = y = 0;
     813            f_sscandate (sflds[1], PREF_MDY, &m, &d, &y);
     814            cal_mjd (m, d, y, &tmp);
     815            *startok = (float)tmp;
     816            if (nsf > 2) {
     817                d = m = y = 0;
     818                f_sscandate (sflds[2], PREF_MDY, &m, &d, &y);
     819                cal_mjd (m, d, y, &tmp);
     820                *endok = (float)tmp;
     821            }
     822        }
     823}
     824
     825/* add startok and endok to string at lp if non-zero.
     826 * return number of characters added.
    755827 */
    756828static int
    757 db_get_field (op, id, bp)
    758 Obj *op;
    759 int id;
    760 char *bp;
    761 {
    762         char *bpsave = bp;
     829get_okdates (char *lp, float *sp, float *ep)
     830{
     831        char *lp0 = lp;
     832
     833        if (*sp || *ep) {
     834            *lp++ = '|';
     835            if (*sp)
     836                lp += fs_date (lp, *sp);
     837            if (*ep) {
     838                *lp++ = '|';
     839                lp += fs_date (lp, *ep);
     840            }
     841        }
     842
     843        return (lp - lp0);
     844}
     845
     846static void
     847write_f (Obj *op, char lp[])
     848{
    763849        double tmp;
    764850
    765         /* include all the enums and in numeric order to give us the best
    766          * possible chance the compiler will implement this as a jump table.
    767          */
    768         switch (id) {
    769         case F_RA:
    770             sprintf (bp, ",");
    771             bp += strlen(bp);
    772             fs_sexa (bp, radhr(op->f_RA), 2, 36000);
    773             bp += strlen(bp);
    774             break;
    775         case F_DEC:
    776             sprintf (bp, ",");
    777             bp += strlen(bp);
    778             fs_sexa (bp, raddeg(op->f_dec), 3, 3600);
    779             bp += strlen(bp);
    780             break;
    781         case F_EPOCH:
    782             mjd_year (op->f_epoch, &tmp);
    783             sprintf (bp, ",%.6g", tmp); /* %.7g gives 2000.001 */
    784             bp += strlen(bp);
    785             break;
    786         case F_MAG:
    787             sprintf (bp, ",%6.2f", get_mag(op));
    788             bp += strlen(bp);
    789             break;
    790         case F_SIZE:
    791             sprintf (bp, ",%.7g", op->f_size);
    792             bp += strlen(bp);
    793             if (op->f_ratio || op->f_pa) {
    794                 sprintf (bp,"|%g|%g", op->f_size*get_ratio(op),
     851        lp += sprintf (lp, "%s,f", op->o_name);
     852        if (op->f_class)
     853            lp += sprintf (lp, "|%c", op->f_class);
     854        if (op->f_spect[0])
     855            lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
     856        *lp++ = ',';
     857        lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
     858        if (op->f_pmRA)
     859            lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
     860        *lp++ = ',';
     861        lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
     862        if (op->f_pmdec)
     863            lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
     864        lp += sprintf (lp, ",%.2f", get_mag(op));
     865        mjd_year (op->f_epoch, &tmp);
     866        lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
     867        lp += sprintf (lp, ",%.7g", op->f_size);
     868        if (op->f_size && (op->f_ratio || op->f_pa))
     869            lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op),
    795870                                                            raddeg(get_pa(op)));
    796                 bp += strlen(bp);
    797             }
    798             break;
    799         case F_CLASS:
    800             if (op->f_class) {
    801                 sprintf (bp, "|%c", op->f_class);
    802                 bp += strlen(bp);
    803             }
    804             break;
    805         case F_SPECT:
    806             if (op->f_spect[0] != '\0') {
    807                 sprintf (bp, "|%c", op->f_spect[0]);
    808                 bp += strlen(bp);
    809                 if (op->f_spect[1] != '\0') {
    810                     sprintf (bp, "%c", op->f_spect[1]);
    811                     bp += strlen(bp);
    812                 }
    813             }
    814             break;
    815 
    816         case E_INC:
    817             sprintf (bp, ",%.7g", op->e_inc);
    818             bp += strlen(bp);
    819             break;
    820         case E_LAN:
    821             sprintf (bp, ",%.7g", op->e_Om);
    822             bp += strlen(bp);
    823             break;
    824         case E_AOP:
    825             sprintf (bp, ",%.7g", op->e_om);
    826             bp += strlen(bp);
    827             break;
    828         case E_A:
    829             sprintf (bp, ",%.7g", op->e_a);
    830             bp += strlen(bp);
    831             break;
    832         case E_N:
    833             /* retired */
    834             sprintf (bp, ",");
    835             bp += strlen(bp);
    836             break;
    837         case E_E:
    838             sprintf (bp, ",%.7g", op->e_e);
    839             bp += strlen(bp);
    840             break;
    841         case E_M:
    842             sprintf (bp, ",%.7g", op->e_M);
    843             bp += strlen(bp);
    844             break;
    845         case E_CEPOCH:
    846             sprintf (bp, ",");
    847             bp += strlen(bp);
    848             fs_date (bp, op->e_cepoch);
    849             bp += strlen(bp);
    850             break;
    851         case E_EPOCH:
    852             sprintf (bp, ",");
    853             bp += strlen(bp);
    854             fs_date (bp, op->e_epoch);
    855             bp += strlen(bp);
    856             break;
    857         case E_M1:
    858             if (op->e_mag.whichm == MAG_gk) {
    859                 sprintf (bp, ",g%.7g", op->e_mag.m1);
    860                 bp += strlen(bp);
    861             } else if (op->e_mag.whichm == MAG_HG) {
    862                 sprintf (bp, ",H%.7g", op->e_mag.m1);
    863                 bp += strlen(bp);
    864             } else {
    865                 sprintf (bp, ",%.7g", op->e_mag.m1);
    866                 bp += strlen(bp);
    867             }
    868             break;
    869         case E_M2:
    870             sprintf (bp, ",%.7g", op->e_mag.m2);
    871             bp += strlen(bp);
    872             break;
    873         case E_SIZE:
    874             sprintf (bp, ",%.7g", op->e_size);
    875             bp += strlen(bp);
    876             break;
    877 
    878         case H_EP:
    879             sprintf (bp, ",");
    880             bp += strlen(bp);
    881             fs_date (bp, op->h_ep);
    882             bp += strlen(bp);
    883             break;
    884         case H_INC:
    885             sprintf (bp, ",%.7g", op->h_inc);
    886             bp += strlen(bp);
    887             break;
    888         case H_LAN:
    889             sprintf (bp, ",%.7g", op->h_Om);
    890             bp += strlen(bp);
    891             break;
    892         case H_AOP:
    893             sprintf (bp, ",%.7g", op->h_om);
    894             bp += strlen(bp);
    895             break;
    896         case H_E:
    897             sprintf (bp, ",%.7g", op->h_e);
    898             bp += strlen(bp);
    899             break;
    900         case H_QP:
    901             sprintf (bp, ",%.7g", op->h_qp);
    902             bp += strlen(bp);
    903             break;
    904         case H_EPOCH:
    905             sprintf (bp, ",");
    906             bp += strlen(bp);
    907             fs_date (bp, op->h_epoch);
    908             bp += strlen(bp);
    909             break;
    910         case H_G:
    911             sprintf (bp, ",%.7g", op->h_g);
    912             bp += strlen(bp);
    913             break;
    914         case H_K:
    915             sprintf (bp, ",%.7g", op->h_k);
    916             bp += strlen(bp);
    917             break;
    918         case H_SIZE:
    919             sprintf (bp, ",%.7g", op->h_size);
    920             bp += strlen(bp);
    921             break;
    922 
    923         case P_EP:
    924             sprintf (bp, ",");
    925             bp += strlen(bp);
    926             fs_date (bp, op->p_ep);
    927             bp += strlen(bp);
    928             break;
    929         case P_INC:
    930             sprintf (bp, ",%.7g", op->p_inc);
    931             bp += strlen(bp);
    932             break;
    933         case P_AOP:
    934             sprintf (bp, ",%.7g", op->p_om);
    935             bp += strlen(bp);
    936             break;
    937         case P_QP:
    938             sprintf (bp, ",%.7g", op->p_qp);
    939             bp += strlen(bp);
    940             break;
    941         case P_LAN:
    942             sprintf (bp, ",%.7g", op->p_Om);
    943             bp += strlen(bp);
    944             break;
    945         case P_EPOCH:
    946             sprintf (bp, ",");
    947             bp += strlen(bp);
    948             fs_date (bp, op->p_epoch);
    949             bp += strlen(bp);
    950             break;
    951         case P_G:
    952             sprintf (bp, ",%.7g", op->p_g);
    953             bp += strlen(bp);
    954             break;
    955         case P_K:
    956             sprintf (bp, ",%.7g", op->p_k);
    957             bp += strlen(bp);
    958             break;
    959         case P_SIZE:
    960             sprintf (bp, ",%.7g", op->p_size);
    961             bp += strlen(bp);
    962             break;
    963 
    964         case ES_EPOCH:
    965             sprintf (bp, ",");
    966             bp += strlen(bp);
    967             fs_date (bp, op->es_epoch);
    968             bp += strlen(bp);
    969             break;
    970         case ES_INC:
    971             sprintf (bp, ",%.7g", op->es_inc);
    972             bp += strlen(bp);
    973             break;
    974         case ES_RAAN:
    975             sprintf (bp, ",%.7g", op->es_raan);
    976             bp += strlen(bp);
    977             break;
    978         case ES_E:
    979             sprintf (bp, ",%.7g", op->es_e);
    980             bp += strlen(bp);
    981             break;
    982         case ES_AP:
    983             sprintf (bp, ",%.7g", op->es_ap);
    984             bp += strlen(bp);
    985             break;
    986         case ES_M:
    987             sprintf (bp, ",%.7g", op->es_M);
    988             bp += strlen(bp);
    989             break;
    990         case ES_N:
    991             sprintf (bp, ",%.7g", op->es_n);
    992             bp += strlen(bp);
    993             break;
    994         case ES_DECAY:
    995             sprintf (bp, ",%.7g", op->es_decay);
    996             bp += strlen(bp);
    997             break;
    998         case ES_ORBIT:
    999             sprintf (bp, ",%d", op->es_orbit);
    1000             bp += strlen(bp);
    1001             break;
    1002         case ES_DRAG:
    1003             sprintf (bp, ",%.7g", op->es_drag);
    1004             bp += strlen(bp);
    1005             break;
    1006 
    1007         default:
    1008             printf ("BUG! db_set_field: bad id: %d\n", id);
    1009             exit (1);
    1010         }
    1011 
    1012         return (bp - bpsave);
     871}
     872
     873static void
     874write_e (Obj *op, char lp[])
     875{
     876        lp += sprintf (lp, "%s,e", op->o_name);
     877        lp += sprintf (lp, ",%.7g", op->e_inc);
     878        lp += sprintf (lp, ",%.7g", op->e_Om);
     879        lp += sprintf (lp, ",%.7g", op->e_om);
     880        lp += sprintf (lp, ",%.7g", op->e_a);
     881        lp += sprintf (lp, ",%.7g", 0.0);               /* retired op->e_n */
     882        lp += sprintf (lp, ",%.7g", op->e_e);
     883        lp += sprintf (lp, ",%.7g", op->e_M);
     884        *lp++ = ',';
     885        lp += fs_date (lp, op->e_cepoch);
     886        lp += get_okdates (lp, &op->e_startok, &op->e_endok);
     887        *lp++ = ',';
     888        lp += fs_date (lp, op->e_epoch);
     889        if (op->e_mag.whichm == MAG_gk)
     890            lp += sprintf (lp, ",g%.7g", op->e_mag.m1);
     891        else if (op->e_mag.whichm == MAG_HG)
     892            lp += sprintf (lp, ",H%.7g", op->e_mag.m1);
     893        else
     894            lp += sprintf (lp, ",%.7g", op->e_mag.m1);
     895        lp += sprintf (lp, ",%.7g", op->e_mag.m2);
     896        lp += sprintf (lp, ",%.7g", op->e_size);
     897}
     898
     899static void
     900write_h (Obj *op, char lp[])
     901{
     902        lp += sprintf (lp, "%s,h", op->o_name);
     903        *lp++ = ',';
     904        lp += fs_date (lp, op->h_ep);
     905        lp += get_okdates (lp, &op->h_startok, &op->h_endok);
     906        lp += sprintf (lp, ",%.7g", op->h_inc);
     907        lp += sprintf (lp, ",%.7g", op->h_Om);
     908        lp += sprintf (lp, ",%.7g", op->h_om);
     909        lp += sprintf (lp, ",%.7g", op->h_e);
     910        lp += sprintf (lp, ",%.7g", op->h_qp);
     911        *lp++ = ',';
     912        lp += fs_date (lp, op->h_epoch);
     913        lp += sprintf (lp, ",%.7g", op->h_g);
     914        lp += sprintf (lp, ",%.7g", op->h_k);
     915        lp += sprintf (lp, ",%.7g", op->h_size);
     916}
     917
     918static void
     919write_p (Obj *op, char lp[])
     920{
     921        lp += sprintf (lp, "%s,p", op->o_name);
     922        *lp++ = ',';
     923        lp += fs_date (lp, op->p_ep);
     924        lp += get_okdates (lp, &op->p_startok, &op->p_endok);
     925        lp += sprintf (lp, ",%.7g", op->p_inc);
     926        lp += sprintf (lp, ",%.7g", op->p_om);
     927        lp += sprintf (lp, ",%.7g", op->p_qp);
     928        lp += sprintf (lp, ",%.7g", op->p_Om);
     929        *lp++ = ',';
     930        lp += fs_date (lp, op->p_epoch);
     931        lp += sprintf (lp, ",%.7g", op->p_g);
     932        lp += sprintf (lp, ",%.7g", op->p_k);
     933        lp += sprintf (lp, ",%.7g", op->p_size);
     934}
     935
     936static void
     937write_E (Obj *op, char lp[])
     938{
     939        lp += sprintf (lp, "%s,E", op->o_name);
     940        *lp++ = ',';
     941        lp += fs_date (lp, op->es_epoch);
     942        lp += get_okdates (lp, &op->es_startok, &op->es_endok);
     943        lp += sprintf (lp, ",%.7g", op->es_inc);
     944        lp += sprintf (lp, ",%.7g", op->es_raan);
     945        lp += sprintf (lp, ",%.7g", op->es_e);
     946        lp += sprintf (lp, ",%.7g", op->es_ap);
     947        lp += sprintf (lp, ",%.7g", op->es_M);
     948        lp += sprintf (lp, ",%.7g", op->es_n);
     949        lp += sprintf (lp, ",%.7g", op->es_decay);
     950        lp += sprintf (lp, ",%d", op->es_orbit);
     951        lp += sprintf (lp, ",%.7g", op->es_drag);
     952}
     953
     954static void
     955write_B (Obj *op, char lp[])
     956{
     957        double tmp;
     958
     959        lp += sprintf (lp, "%s,B", op->o_name);
     960        if (op->f_class)
     961            lp += sprintf (lp, "|%c", op->f_class);
     962        if (op->f_spect[0])
     963            lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
     964        if (op->b_2spect[0])
     965            lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect);
     966        *lp++ = ',';
     967        lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
     968        if (op->f_pmRA)
     969            lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
     970        *lp++ = ',';
     971        lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
     972        if (op->f_pmdec)
     973            lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
     974        lp += sprintf (lp, ",%.2f", get_mag(op));
     975        lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE);
     976        mjd_year (op->f_epoch, &tmp);
     977        lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
     978        if (op->b_nbp == 0) {
     979            lp += sprintf (lp, ",%.6g",  op->b_bo.bo_a);
     980            lp += sprintf (lp, "|%.6g",  op->b_bo.bo_i);
     981            lp += sprintf (lp, "|%.6g",  op->b_bo.bo_O);
     982            lp += sprintf (lp, "|%.6g",  op->b_bo.bo_e);
     983            lp += sprintf (lp, "|%.6g",  op->b_bo.bo_T);
     984            lp += sprintf (lp, "|%.6g",  op->b_bo.bo_o);
     985            lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P);
     986        } else {
     987            int i;
     988
     989            for (i = 0; i < op->b_nbp; i++) {
     990                BinPos *bp = &op->b_bp[i];
     991                lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep);
     992                lp += sprintf (lp, "|%.6g", bp->bp_sep);
     993                lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa));
     994            }
     995        }
     996}
     997
     998static void
     999write_P (Obj *op, char lp[])
     1000{
     1001
     1002        lp += sprintf (lp, "%s,P", op->o_name);
    10131003}
    10141004
    10151005/* For RCS Only -- Do Not Edit */
    1016 static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2001-10-22 12:08:26 $ $Revision: 1.2 $ $Name: not supported by cvs2svn $"};
     1006static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2004-06-15 16:52:38 $ $Revision: 1.3 $ $Name: not supported by cvs2svn $"};
Note: See TracChangeset for help on using the changeset viewer.