| 1 | /* code to convert between .edb format and an Obj */
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #include <stdio.h>
 | 
|---|
| 4 | #include <ctype.h>
 | 
|---|
| 5 | #include <math.h>
 | 
|---|
| 6 | #include <stdlib.h>
 | 
|---|
| 7 | #include <string.h>
 | 
|---|
| 8 | 
 | 
|---|
| 9 | #include "astro.h"
 | 
|---|
| 10 | #include "preferences.h"
 | 
|---|
| 11 | 
 | 
|---|
| 12 | 
 | 
|---|
| 13 | int get_fields (char *s, int delim, char *fields[]);
 | 
|---|
| 14 | 
 | 
|---|
| 15 | #define MAXDBLINE       256     /* longest allowed db line */
 | 
|---|
| 16 | 
 | 
|---|
| 17 | #define FLDSEP          ','     /* major field separator */
 | 
|---|
| 18 | #define SUBFLD          '|'     /* subfield separator */
 | 
|---|
| 19 | #define MAXFLDS 20              /* must be more than on any expected line */
 | 
|---|
| 20 | 
 | 
|---|
| 21 | static char *enm (char *flds[MAXFLDS]);
 | 
|---|
| 22 | static int crack_f (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 23 | static int crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 24 | static int crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 25 | static int crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 26 | static int crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 27 | static int crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 28 | static int crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[]);
 | 
|---|
| 29 | static int crack_name (Obj *op, char *flds[MAXFLDS], int nf,
 | 
|---|
| 30 |     char nm[][MAXNM], int nnm);
 | 
|---|
| 31 | static void crack_year (char *bp, double *p);
 | 
|---|
| 32 | static void crack_okdates (char *fld, float *startok, float *endok);
 | 
|---|
| 33 | static int get_okdates (char *lp, float *sp, float *ep);
 | 
|---|
| 34 | static int tle_sum (char *l);
 | 
|---|
| 35 | static double tle_fld (char *l, int from, int thru);
 | 
|---|
| 36 | static double tle_expfld (char *l, int start);
 | 
|---|
| 37 | static void write_f (Obj *op, char lp[]);
 | 
|---|
| 38 | static void write_e (Obj *op, char lp[]);
 | 
|---|
| 39 | static void write_h (Obj *op, char lp[]);
 | 
|---|
| 40 | static void write_p (Obj *op, char lp[]);
 | 
|---|
| 41 | static void write_E (Obj *op, char lp[]);
 | 
|---|
| 42 | static void write_P (Obj *op, char lp[]);
 | 
|---|
| 43 | static void write_B (Obj *op, char lp[]);
 | 
|---|
| 44 | 
 | 
|---|
| 45 | /* crack the given .edb database line into op.
 | 
|---|
| 46 |  * if ok
 | 
|---|
| 47 |  *   return number of names in nm[], or 1 if nm == NULL
 | 
|---|
| 48 |  * else
 | 
|---|
| 49 |  *   if whynot
 | 
|---|
| 50 |  *     if not even a candidate
 | 
|---|
| 51 |  *       set whynot[0] = '\0'
 | 
|---|
| 52 |  *     else
 | 
|---|
| 53 |  *       fill whynot with reason message.
 | 
|---|
| 54 |  *   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.
 | 
|---|
| 57 |  */
 | 
|---|
| 58 | int
 | 
|---|
| 59 | db_crack_line (char s[], Obj *op, char nm[][MAXNM], int nnm, char whynot[])
 | 
|---|
| 60 | {
 | 
|---|
| 61 |         char copy[MAXDBLINE];   /* work copy; leave s untouched */
 | 
|---|
| 62 |         char *flds[MAXFLDS];    /* point to each field for easy reference */
 | 
|---|
| 63 |         int nf;
 | 
|---|
| 64 |         int i;
 | 
|---|
| 65 | 
 | 
|---|
| 66 |         /* init no response */
 | 
|---|
| 67 |         if (whynot)
 | 
|---|
| 68 |             whynot[0] = '\0';
 | 
|---|
| 69 | 
 | 
|---|
| 70 |         /* basic initial check */
 | 
|---|
| 71 |         if (dbline_candidate (s) < 0)
 | 
|---|
| 72 |             return (-1);
 | 
|---|
| 73 | 
 | 
|---|
| 74 |         /* do all the parsing on a copy */
 | 
|---|
| 75 |         (void) strcpy (copy, s);
 | 
|---|
| 76 |         i = strlen(copy);
 | 
|---|
| 77 |         if (copy[i-1] == '\n')
 | 
|---|
| 78 |             copy[i-1] = '\0';
 | 
|---|
| 79 | 
 | 
|---|
| 80 |         /* parse into main fields */
 | 
|---|
| 81 |         nf = get_fields (copy, FLDSEP, flds);
 | 
|---|
| 82 | 
 | 
|---|
| 83 |         /* need at least 2: name and type */
 | 
|---|
| 84 |         if (nf < 2) {
 | 
|---|
| 85 |             if (whynot)
 | 
|---|
| 86 |                 sprintf (whynot, "Bogus: %s", s);
 | 
|---|
| 87 |             return (-1);
 | 
|---|
| 88 |         }
 | 
|---|
| 89 | 
 | 
|---|
| 90 |         /* switch out on type of object - the second field */
 | 
|---|
| 91 |         switch (flds[1][0]) {
 | 
|---|
| 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;
 | 
|---|
| 122 | 
 | 
|---|
| 123 |         case 'P':
 | 
|---|
| 124 |             if (crack_P (op, flds, nf, whynot) < 0)
 | 
|---|
| 125 |                 return (-1);
 | 
|---|
| 126 |             break;
 | 
|---|
| 127 | 
 | 
|---|
| 128 |         default:
 | 
|---|
| 129 |             if (whynot)
 | 
|---|
| 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'.
 | 
|---|
| 140 |  */
 | 
|---|
| 141 | void
 | 
|---|
| 142 | db_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);
 | 
|---|
| 187 | }
 | 
|---|
| 188 | 
 | 
|---|
| 189 | /* given 3 lines, first of which is name and next 2 are TLE, fill op.
 | 
|---|
| 190 |  * we skip leading whitespace on all lines.
 | 
|---|
| 191 |  * we do /not/ assume the 2 TLE lines are 0 terminated, but we do reach out into
 | 
|---|
| 192 |  *   each as far as 69 chars.
 | 
|---|
| 193 |  * we detect nonconformance as efficiently as possible.
 | 
|---|
| 194 |  * name ends at first '\0', '\r' or '\n'.
 | 
|---|
| 195 |  * if ok return 0 else return -1
 | 
|---|
| 196 |  */
 | 
|---|
| 197 | int
 | 
|---|
| 198 | db_tle (char *name, char *l1, char *l2, Obj *op)
 | 
|---|
| 199 | {
 | 
|---|
| 200 |         double ep;
 | 
|---|
| 201 |         int i;
 | 
|---|
| 202 | 
 | 
|---|
| 203 |         /* check for correct line numbers, macthing satellite numbers and
 | 
|---|
| 204 |          * correct checksums.
 | 
|---|
| 205 |          */
 | 
|---|
| 206 |         while (isspace(*l1))
 | 
|---|
| 207 |             l1++;
 | 
|---|
| 208 |         if (*l1 != '1')
 | 
|---|
| 209 |             return (-1);
 | 
|---|
| 210 |         while (isspace(*l2))
 | 
|---|
| 211 |             l2++;
 | 
|---|
| 212 |         if (*l2 != '2')
 | 
|---|
| 213 |             return (-1);
 | 
|---|
| 214 |         if (strncmp (l1+2, l2+2, 5))
 | 
|---|
| 215 |             return (-1);
 | 
|---|
| 216 |         if (tle_sum (l1) < 0)
 | 
|---|
| 217 |             return (-1);
 | 
|---|
| 218 |         if (tle_sum (l2) < 0)
 | 
|---|
| 219 |             return (-1);
 | 
|---|
| 220 | 
 | 
|---|
| 221 |         /* assume it's ok from here out */
 | 
|---|
| 222 | 
 | 
|---|
| 223 |         /* fresh */
 | 
|---|
| 224 |         zero_mem ((void *)op, sizeof(ObjES));
 | 
|---|
| 225 |         op->o_type = EARTHSAT;
 | 
|---|
| 226 | 
 | 
|---|
| 227 |         /* name, sans leading and trailing whitespace */
 | 
|---|
| 228 |         while (isspace(*name))
 | 
|---|
| 229 |             name++;
 | 
|---|
| 230 |         i = strcspn (name, "\r\n");
 | 
|---|
| 231 |         while (i > 0 && name[i-1] == ' ')
 | 
|---|
| 232 |             --i;
 | 
|---|
| 233 |         if (i == 0)
 | 
|---|
| 234 |             return (-1);
 | 
|---|
| 235 |         if (i > MAXNM-1)
 | 
|---|
| 236 |             i = MAXNM-1;
 | 
|---|
| 237 |         sprintf (op->o_name, "%.*s", i, name);
 | 
|---|
| 238 | 
 | 
|---|
| 239 |         /* goodies from "line 1" */
 | 
|---|
| 240 |         op->es_drag = (float) tle_expfld (l1, 54);
 | 
|---|
| 241 |         op->es_decay = (float) tle_fld (l1, 34, 43);
 | 
|---|
| 242 |         i = (int) tle_fld (l1, 19, 20);
 | 
|---|
| 243 |         if (i < 57)
 | 
|---|
| 244 |             i += 100;
 | 
|---|
| 245 |         cal_mjd (1, tle_fld(l1, 21, 32), i+1900, &ep);
 | 
|---|
| 246 |         op->es_epoch = ep;
 | 
|---|
| 247 | 
 | 
|---|
| 248 |         /* goodies from "line 2" */
 | 
|---|
| 249 |         op->es_n = tle_fld (l2, 53, 63);
 | 
|---|
| 250 |         op->es_inc = (float)tle_fld (l2, 9, 16);
 | 
|---|
| 251 |         op->es_raan = (float)tle_fld (l2, 18, 25);
 | 
|---|
| 252 |         op->es_e = (float)(tle_fld (l2, 27, 33) * 1e-7);
 | 
|---|
| 253 |         op->es_ap = (float)tle_fld (l2, 35, 42);
 | 
|---|
| 254 |         op->es_M = (float)tle_fld (l2, 44, 51);
 | 
|---|
| 255 |         op->es_orbit = (int)tle_fld (l2, 64, 68);
 | 
|---|
| 256 | 
 | 
|---|
| 257 |         /* yes! */
 | 
|---|
| 258 |         return (0);
 | 
|---|
| 259 | }
 | 
|---|
| 260 | 
 | 
|---|
| 261 | /* return 0 if op has no date range information or what it does have brackets
 | 
|---|
| 262 |  * now, else -1
 | 
|---|
| 263 |  */
 | 
|---|
| 264 | int
 | 
|---|
| 265 | dateRangeOK (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;
 | 
|---|
| 286 |         default:
 | 
|---|
| 287 |             return (0);
 | 
|---|
| 288 |         }
 | 
|---|
| 289 | 
 | 
|---|
| 290 |         if (*sp <= mjd && (!*ep || mjd <= *ep))
 | 
|---|
| 291 |             return (0);
 | 
|---|
| 292 |         return (-1);
 | 
|---|
| 293 | }
 | 
|---|
| 294 | 
 | 
|---|
| 295 | /* given a null-terminated string, fill in fields[] with the starting addresses
 | 
|---|
| 296 |  * of each field delimited by delim or '\0'.
 | 
|---|
| 297 |  * N.B. each character matching delim is REPLACED BY '\0' IN PLACE.
 | 
|---|
| 298 |  * N.B. 0-length fields count, so even if *s=='\0' we return 1.
 | 
|---|
| 299 |  * return the number of fields.
 | 
|---|
| 300 |  */
 | 
|---|
| 301 | int
 | 
|---|
| 302 | get_fields (char *s, int delim, char *fields[])
 | 
|---|
| 303 | {
 | 
|---|
| 304 |         int n;
 | 
|---|
| 305 |         char c;
 | 
|---|
| 306 | 
 | 
|---|
| 307 |         *fields = s;
 | 
|---|
| 308 |         n = 0;
 | 
|---|
| 309 |         do {
 | 
|---|
| 310 |             c = *s++;
 | 
|---|
| 311 |             if (c == delim || c == '\0') {
 | 
|---|
| 312 |                 s[-1] = '\0';
 | 
|---|
| 313 |                 *++fields = s;
 | 
|---|
| 314 |                 n++;
 | 
|---|
| 315 |             }
 | 
|---|
| 316 |         } while (c);
 | 
|---|
| 317 | 
 | 
|---|
| 318 |         return (n);
 | 
|---|
| 319 | }
 | 
|---|
| 320 | 
 | 
|---|
| 321 | /* return 0 if buf qualifies as a database line worthy of a cracking
 | 
|---|
| 322 |  * attempt, else -1.
 | 
|---|
| 323 |  */
 | 
|---|
| 324 | int
 | 
|---|
| 325 | dbline_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 */
 | 
|---|
| 333 | static int
 | 
|---|
| 334 | tle_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 |  */
 | 
|---|
| 355 | static double
 | 
|---|
| 356 | tle_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 |  */
 | 
|---|
| 367 | static double
 | 
|---|
| 368 | tle_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 | 
 | 
|---|
| 380 | static int
 | 
|---|
| 381 | crack_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: type f needs 5-7 fields, not %d",
 | 
|---|
| 390 |                                                                 enm(flds),nf);
 | 
|---|
| 391 |             return (-1);
 | 
|---|
| 392 |         }
 | 
|---|
| 393 | 
 | 
|---|
| 394 |         zero_mem ((void *)op, sizeof(ObjF));
 | 
|---|
| 395 |         op->o_type = FIXED;
 | 
|---|
| 396 | 
 | 
|---|
| 397 |         nsf = get_fields(flds[1], SUBFLD, sflds);
 | 
|---|
| 398 |         if (nsf > 1) {
 | 
|---|
| 399 |             switch (sflds[1][0]) {
 | 
|---|
| 400 |             case 'A': case 'B': case 'C': case 'D': case 'F': case 'G':
 | 
|---|
| 401 |             case 'H': case 'K': case 'J': case 'L': case 'M': case 'N':
 | 
|---|
| 402 |             case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
 | 
|---|
| 403 |             case 'U': case 'V': case 'Y':
 | 
|---|
| 404 |                 op->f_class = sflds[1][0];
 | 
|---|
| 405 |                 if (op->f_class == 'B')
 | 
|---|
| 406 |                     op->f_class = 'D';  /* merge B and D since BINARYSTAR */
 | 
|---|
| 407 |                 break;
 | 
|---|
| 408 |             default:
 | 
|---|
| 409 |                 if (whynot)
 | 
|---|
| 410 |                     sprintf (whynot, "%s: Bad f class: %c", enm(flds),
 | 
|---|
| 411 |                                                                 sflds[1][0]);
 | 
|---|
| 412 |                 return (-1);
 | 
|---|
| 413 |             }
 | 
|---|
| 414 |         } else
 | 
|---|
| 415 |             op->f_class = 'T';          /* default to star-like */
 | 
|---|
| 416 |         if (nsf > 2) {
 | 
|---|
| 417 |             /* fill f_spect all the way */
 | 
|---|
| 418 |             char buf[sizeof(op->f_spect)+1];
 | 
|---|
| 419 |             memset (buf, 0, sizeof(buf));
 | 
|---|
| 420 |             sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
 | 
|---|
| 421 |             memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
 | 
|---|
| 422 |         }
 | 
|---|
| 423 | 
 | 
|---|
| 424 |         nsf = get_fields(flds[2], SUBFLD, sflds);
 | 
|---|
| 425 |         f_scansexa (sflds[0], &tmp);
 | 
|---|
| 426 |         op->f_RA = (float) hrrad(tmp);
 | 
|---|
| 427 |         if (nsf > 1)
 | 
|---|
| 428 |             op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
 | 
|---|
| 429 | 
 | 
|---|
| 430 |         nsf = get_fields(flds[3], SUBFLD, sflds);
 | 
|---|
| 431 |         f_scansexa (sflds[0], &tmp);
 | 
|---|
| 432 |         op->f_dec = (float) degrad(tmp);
 | 
|---|
| 433 |         if (nsf > 1)
 | 
|---|
| 434 |             op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
 | 
|---|
| 435 |         if (fabs(op->f_dec) < PI/2)
 | 
|---|
| 436 |             op->f_pmRA /= cos (op->f_dec);
 | 
|---|
| 437 | 
 | 
|---|
| 438 |         set_fmag (op, atod(flds[4]));
 | 
|---|
| 439 | 
 | 
|---|
| 440 |         if (nf > 5 && flds[5][0]) {
 | 
|---|
| 441 |             tmp = op->f_epoch;
 | 
|---|
| 442 |             crack_year (flds[5], &tmp);
 | 
|---|
| 443 |             op->f_epoch = (float) tmp;
 | 
|---|
| 444 |         } else
 | 
|---|
| 445 |             op->f_epoch = J2000;        /* default */
 | 
|---|
| 446 | 
 | 
|---|
| 447 |         if (nf > 6) {
 | 
|---|
| 448 |             op->f_size = (float) atod(flds[6]);
 | 
|---|
| 449 | 
 | 
|---|
| 450 |             /* optional minor axis and position angle subfields */
 | 
|---|
| 451 |             nsf = get_fields(flds[6], SUBFLD, sflds);
 | 
|---|
| 452 |             if (nsf == 3) {
 | 
|---|
| 453 |                 set_ratio(op, op->s_size, atod(sflds[1]));
 | 
|---|
| 454 |                 set_pa(op,degrad(atod(sflds[2])));
 | 
|---|
| 455 |             } else {
 | 
|---|
| 456 |                 set_ratio(op,1,1);      /* round */
 | 
|---|
| 457 |                 set_pa(op,0.0);
 | 
|---|
| 458 |             }
 | 
|---|
| 459 |         }
 | 
|---|
| 460 | 
 | 
|---|
| 461 |         return (0);
 | 
|---|
| 462 | }
 | 
|---|
| 463 | 
 | 
|---|
| 464 | static int
 | 
|---|
| 465 | crack_e (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 466 | {
 | 
|---|
| 467 |         if (nf != 13 && nf != 14) {
 | 
|---|
| 468 |             if (whynot)
 | 
|---|
| 469 |                 sprintf (whynot, "%s: type e needs 13 or 14 fields, not %d",
 | 
|---|
| 470 |                                                                 enm(flds), nf);
 | 
|---|
| 471 |             return (-1);
 | 
|---|
| 472 |         }
 | 
|---|
| 473 | 
 | 
|---|
| 474 |         zero_mem ((void *)op, sizeof(ObjE));
 | 
|---|
| 475 |         op->o_type = ELLIPTICAL;
 | 
|---|
| 476 | 
 | 
|---|
| 477 |         op->e_inc = (float) atod (flds[2]);
 | 
|---|
| 478 |         op->e_Om = (float) atod (flds[3]);
 | 
|---|
| 479 |         op->e_om = (float) atod (flds[4]);
 | 
|---|
| 480 |         op->e_a = (float) atod (flds[5]);
 | 
|---|
| 481 |         /* retired op->e_n = (float) atod (flds[6]); */
 | 
|---|
| 482 |         op->e_e = atod (flds[7]);
 | 
|---|
| 483 |         op->e_M = (float) atod (flds[8]);
 | 
|---|
| 484 |         crack_year (flds[9], &op->e_cepoch);
 | 
|---|
| 485 |         crack_okdates (flds[9], &op->e_startok, &op->e_endok);
 | 
|---|
| 486 |         crack_year (flds[10], &op->e_epoch);
 | 
|---|
| 487 | 
 | 
|---|
| 488 |         /* magnitude model gk or HG(default). allow prefixes in either field */
 | 
|---|
| 489 |         op->e_mag.whichm = flds[11][0] == 'g' ? MAG_gk : MAG_HG;
 | 
|---|
| 490 |         if (isdigit(flds[11][0]))
 | 
|---|
| 491 |             op->e_mag.m1 = (float) atod(&flds[11][0]);
 | 
|---|
| 492 |         else
 | 
|---|
| 493 |             op->e_mag.m1 = (float) atod(&flds[11][1]);
 | 
|---|
| 494 |         if (isdigit(flds[12][0]))
 | 
|---|
| 495 |             op->e_mag.m2 = (float) atod(&flds[12][0]);
 | 
|---|
| 496 |         else
 | 
|---|
| 497 |             op->e_mag.m2 = (float) atod(&flds[12][1]);
 | 
|---|
| 498 | 
 | 
|---|
| 499 |         if (nf == 14)
 | 
|---|
| 500 |             op->e_size = (float) atod (flds[13]);
 | 
|---|
| 501 | 
 | 
|---|
| 502 |         return (0);
 | 
|---|
| 503 | }
 | 
|---|
| 504 | 
 | 
|---|
| 505 | static int
 | 
|---|
| 506 | crack_h (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 507 | {
 | 
|---|
| 508 |         if (nf != 11 && nf != 12) {
 | 
|---|
| 509 |             if (whynot)
 | 
|---|
| 510 |                 sprintf (whynot, "%s: type h needs 11 or 12 fields, not %d",
 | 
|---|
| 511 |                                                                 enm(flds), nf);
 | 
|---|
| 512 |             return (-1);
 | 
|---|
| 513 |         }
 | 
|---|
| 514 | 
 | 
|---|
| 515 |         zero_mem ((void *)op, sizeof(ObjH));
 | 
|---|
| 516 |         op->o_type = HYPERBOLIC;
 | 
|---|
| 517 | 
 | 
|---|
| 518 |         crack_year (flds[2], &op->h_ep);
 | 
|---|
| 519 |         crack_okdates (flds[2], &op->h_startok, &op->h_endok);
 | 
|---|
| 520 |         op->h_inc = (float) atod (flds[3]);
 | 
|---|
| 521 |         op->h_Om = (float) atod (flds[4]);
 | 
|---|
| 522 |         op->h_om = (float) atod (flds[5]);
 | 
|---|
| 523 |         op->h_e = (float) atod (flds[6]);
 | 
|---|
| 524 |         op->h_qp = (float) atod (flds[7]);
 | 
|---|
| 525 |         crack_year (flds[8], &op->h_epoch);
 | 
|---|
| 526 |         op->h_g = (float) atod (flds[9]);
 | 
|---|
| 527 |         op->h_k = (float) atod (flds[10]);
 | 
|---|
| 528 | 
 | 
|---|
| 529 |         if (nf == 12)
 | 
|---|
| 530 |             op->h_size = (float) atod (flds[11]);
 | 
|---|
| 531 | 
 | 
|---|
| 532 |         return (0);
 | 
|---|
| 533 | }
 | 
|---|
| 534 | 
 | 
|---|
| 535 | static int
 | 
|---|
| 536 | crack_p (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 537 | {
 | 
|---|
| 538 |         if (nf != 10 && nf != 11) {
 | 
|---|
| 539 |             if (whynot)
 | 
|---|
| 540 |                 sprintf (whynot, "%s: type p needs 10 or 11 fields, not %d",    
 | 
|---|
| 541 |                                                                 enm(flds), nf);
 | 
|---|
| 542 |             return (-1);
 | 
|---|
| 543 |         }
 | 
|---|
| 544 | 
 | 
|---|
| 545 |         zero_mem ((void *)op, sizeof(ObjP));
 | 
|---|
| 546 |         op->o_type = PARABOLIC;
 | 
|---|
| 547 | 
 | 
|---|
| 548 |         crack_year (flds[2], &op->p_ep);
 | 
|---|
| 549 |         crack_okdates (flds[2], &op->p_startok, &op->p_endok);
 | 
|---|
| 550 |         op->p_inc = (float) atod (flds[3]);
 | 
|---|
| 551 |         op->p_om = (float) atod (flds[4]);
 | 
|---|
| 552 |         op->p_qp = (float) atod (flds[5]);
 | 
|---|
| 553 |         op->p_Om = (float) atod (flds[6]);
 | 
|---|
| 554 |         crack_year (flds[7], &op->p_epoch);
 | 
|---|
| 555 |         op->p_g = (float) atod (flds[8]);
 | 
|---|
| 556 |         op->p_k = (float) atod (flds[9]);
 | 
|---|
| 557 | 
 | 
|---|
| 558 |         if (nf == 11)
 | 
|---|
| 559 |             op->p_size = (float) atod (flds[10]);
 | 
|---|
| 560 | 
 | 
|---|
| 561 |         return (0);
 | 
|---|
| 562 | }
 | 
|---|
| 563 | 
 | 
|---|
| 564 | static int
 | 
|---|
| 565 | crack_E (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 566 | {
 | 
|---|
| 567 |         if (nf != 11 && nf != 12) {
 | 
|---|
| 568 |             if (whynot)
 | 
|---|
| 569 |                 sprintf (whynot, "%s: type E needs 11 or 12 fields, not %d",
 | 
|---|
| 570 |                                                             enm(flds), nf);
 | 
|---|
| 571 |             return (-1);
 | 
|---|
| 572 |         }
 | 
|---|
| 573 | 
 | 
|---|
| 574 |         zero_mem ((void *)op, sizeof(ObjES));
 | 
|---|
| 575 |         op->o_type = EARTHSAT;
 | 
|---|
| 576 |         crack_year (flds[2], &op->es_epoch);
 | 
|---|
| 577 |         crack_okdates (flds[2], &op->es_startok, &op->es_endok);
 | 
|---|
| 578 |         op->es_inc = (float) atod (flds[3]);
 | 
|---|
| 579 |         op->es_raan = (float) atod (flds[4]);
 | 
|---|
| 580 |         op->es_e = (float) atod (flds[5]);
 | 
|---|
| 581 |         op->es_ap = (float) atod (flds[6]);
 | 
|---|
| 582 |         op->es_M = (float) atod (flds[7]);
 | 
|---|
| 583 |         op->es_n = atod (flds[8]);
 | 
|---|
| 584 |         op->es_decay = (float) atod (flds[9]);
 | 
|---|
| 585 |         op->es_orbit = atoi (flds[10]);
 | 
|---|
| 586 |         if (nf == 12)
 | 
|---|
| 587 |             op->es_drag = (float) atod (flds[11]);
 | 
|---|
| 588 | 
 | 
|---|
| 589 |         return (0);
 | 
|---|
| 590 | }
 | 
|---|
| 591 | 
 | 
|---|
| 592 | static int
 | 
|---|
| 593 | crack_P (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 594 | {
 | 
|---|
| 595 |         Obj *bi;
 | 
|---|
| 596 |         int nbi;
 | 
|---|
| 597 |         int i;
 | 
|---|
| 598 | 
 | 
|---|
| 599 |         nbi = getBuiltInObjs (&bi);
 | 
|---|
| 600 | 
 | 
|---|
| 601 |         for (i = 0; i < nbi; i++) {
 | 
|---|
| 602 |             Obj *bop = bi + i;
 | 
|---|
| 603 |             if (is_type(bop,PLANETM) && !strcmp (flds[0], bop->o_name)) {
 | 
|---|
| 604 |                 memcpy ((void *)op, bop, sizeof(ObjPl));
 | 
|---|
| 605 |                 return (0);
 | 
|---|
| 606 |             }
 | 
|---|
| 607 |         }
 | 
|---|
| 608 | 
 | 
|---|
| 609 |         if (whynot)
 | 
|---|
| 610 |             sprintf (whynot, "%s: Unknown planet or moon", enm(flds));
 | 
|---|
| 611 |         return (-1);
 | 
|---|
| 612 | }
 | 
|---|
| 613 | 
 | 
|---|
| 614 | static int
 | 
|---|
| 615 | crack_B (Obj *op, char *flds[MAXFLDS], int nf, char whynot[])
 | 
|---|
| 616 | {
 | 
|---|
| 617 |         char *sflds[MAXFLDS];
 | 
|---|
| 618 |         double tmp;
 | 
|---|
| 619 |         int nsf;
 | 
|---|
| 620 | 
 | 
|---|
| 621 |         if (nf != 7) {
 | 
|---|
| 622 |             if (whynot)
 | 
|---|
| 623 |                 sprintf (whynot, "%s: B need 7 fields, not %d", enm(flds), nf);
 | 
|---|
| 624 |             return (-1);
 | 
|---|
| 625 |         }
 | 
|---|
| 626 | 
 | 
|---|
| 627 |         zero_mem ((void *)op, sizeof(ObjB));
 | 
|---|
| 628 |         op->o_type = BINARYSTAR;
 | 
|---|
| 629 | 
 | 
|---|
| 630 |         nsf = get_fields(flds[1], SUBFLD, sflds);
 | 
|---|
| 631 |         if (nsf > 1) {
 | 
|---|
| 632 |             switch (sflds[1][0]) {
 | 
|---|
| 633 |             case 'a': case 'c': case 'e': case 'x': case 'y': case 'o':
 | 
|---|
| 634 |             case 's': case 't': case 'u': case 'v': case 'b': case 'd':
 | 
|---|
| 635 |             case 'q': case 'r': case 'p': case 'U': case 'V': case 'Y':
 | 
|---|
| 636 |                 op->f_class = sflds[1][0];
 | 
|---|
| 637 |                 break;
 | 
|---|
| 638 |             default:
 | 
|---|
| 639 |                 if (whynot)
 | 
|---|
| 640 |                     sprintf (whynot, "%s: Bad B class: %c", enm(flds),
 | 
|---|
| 641 |                                                                 sflds[1][0]);
 | 
|---|
| 642 |                 return (-1);
 | 
|---|
| 643 |             }
 | 
|---|
| 644 |         }
 | 
|---|
| 645 |         if (nsf > 2) {
 | 
|---|
| 646 |             /* fill f_spect all the way */
 | 
|---|
| 647 |             char buf[sizeof(op->f_spect)+1];
 | 
|---|
| 648 |             memset (buf, 0, sizeof(buf));
 | 
|---|
| 649 |             sprintf (buf, "%.*s", (int)sizeof(op->f_spect), sflds[2]);
 | 
|---|
| 650 |             memcpy (op->f_spect, buf, (int)sizeof(op->f_spect));
 | 
|---|
| 651 |         }
 | 
|---|
| 652 |         if (nsf > 3) {
 | 
|---|
| 653 |             /* fill b_2spect all the way */
 | 
|---|
| 654 |             char buf[sizeof(op->b_2spect)+1];
 | 
|---|
| 655 |             memset (buf, 0, sizeof(buf));
 | 
|---|
| 656 |             sprintf (buf, "%.*s", (int)sizeof(op->b_2spect), sflds[3]);
 | 
|---|
| 657 |             memcpy (op->b_2spect, buf, (int)sizeof(op->b_2spect));
 | 
|---|
| 658 |         }
 | 
|---|
| 659 | 
 | 
|---|
| 660 |         nsf = get_fields(flds[2], SUBFLD, sflds);
 | 
|---|
| 661 |         f_scansexa (sflds[0], &tmp);
 | 
|---|
| 662 |         op->f_RA = (float) hrrad(tmp);
 | 
|---|
| 663 |         if (nsf > 1)
 | 
|---|
| 664 |             op->f_pmRA = (float) 1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
 | 
|---|
| 665 | 
 | 
|---|
| 666 |         nsf = get_fields(flds[3], SUBFLD, sflds);
 | 
|---|
| 667 |         f_scansexa (sflds[0], &tmp);
 | 
|---|
| 668 |         op->f_dec = (float) degrad(tmp);
 | 
|---|
| 669 |         if (nsf > 1)
 | 
|---|
| 670 |             op->f_pmdec = (float)1.327e-11*atod(sflds[1]);/*mas/yr->rad/dy*/
 | 
|---|
| 671 |         if (fabs(op->f_dec) < PI/2)
 | 
|---|
| 672 |             op->f_pmRA /= cos (op->f_dec);
 | 
|---|
| 673 | 
 | 
|---|
| 674 |         nsf = get_fields(flds[4], SUBFLD, sflds);
 | 
|---|
| 675 |         if (nsf > 0)
 | 
|---|
| 676 |             set_fmag (op, atod(sflds[0]));
 | 
|---|
| 677 |         if (nsf > 1)
 | 
|---|
| 678 |             op->b_2mag = (short)floor((atod(sflds[1]))*MAGSCALE + 0.5);
 | 
|---|
| 679 | 
 | 
|---|
| 680 |         if (flds[5][0]) {
 | 
|---|
| 681 |             tmp = op->f_epoch;
 | 
|---|
| 682 |             crack_year (flds[5], &tmp);
 | 
|---|
| 683 |             op->f_epoch = (float) tmp;
 | 
|---|
| 684 |         } else
 | 
|---|
| 685 |             op->f_epoch = J2000;        /* default */
 | 
|---|
| 686 | 
 | 
|---|
| 687 |         nsf = get_fields(flds[6], SUBFLD, sflds);
 | 
|---|
| 688 |         if (nsf == 7) {
 | 
|---|
| 689 |             int l;
 | 
|---|
| 690 |             char c;
 | 
|---|
| 691 | 
 | 
|---|
| 692 |             op->b_bo.bo_a = atod(sflds[0]);
 | 
|---|
| 693 |             op->b_bo.bo_i = atod(sflds[1]);
 | 
|---|
| 694 |             op->b_bo.bo_O = atod(sflds[2]);
 | 
|---|
| 695 |             op->b_bo.bo_e = atod(sflds[3]);
 | 
|---|
| 696 |             op->b_bo.bo_T = atod(sflds[4]);
 | 
|---|
| 697 |             op->b_bo.bo_o = atod(sflds[5]);
 | 
|---|
| 698 |             op->b_bo.bo_P = atod(sflds[6]);
 | 
|---|
| 699 | 
 | 
|---|
| 700 |             /* reject some weird entries actually seen in real lists */
 | 
|---|
| 701 |             if (op->b_bo.bo_a <= 0) {
 | 
|---|
| 702 |                 if (whynot)
 | 
|---|
| 703 |                     sprintf (whynot, "%s: Bogus B semi major axis: %g",
 | 
|---|
| 704 |                                                     enm(flds), op->b_bo.bo_a);
 | 
|---|
| 705 |                 return (-1);
 | 
|---|
| 706 |             }
 | 
|---|
| 707 |             if (op->b_bo.bo_P <= 0) {
 | 
|---|
| 708 |                 if (whynot)
 | 
|---|
| 709 |                     sprintf (whynot, "%s: Bogus B period: %g", enm(flds),
 | 
|---|
| 710 |                                                                 op->b_bo.bo_P);
 | 
|---|
| 711 |                 return (-1);
 | 
|---|
| 712 |             }
 | 
|---|
| 713 | 
 | 
|---|
| 714 |             /* scale period */
 | 
|---|
| 715 |             l = strlen (sflds[6]);
 | 
|---|
| 716 |             c = sflds[6][l-1];
 | 
|---|
| 717 |             switch (c) {
 | 
|---|
| 718 |             case 'y': case 'Y':
 | 
|---|
| 719 |                 break;
 | 
|---|
| 720 |             case 'h': case 'H':
 | 
|---|
| 721 |                 op->b_bo.bo_P /= (24.0*365.25);
 | 
|---|
| 722 |                 break;
 | 
|---|
| 723 |             case 'd': case 'D':
 | 
|---|
| 724 |                 op->b_bo.bo_P /= 365.25;
 | 
|---|
| 725 |                 break;
 | 
|---|
| 726 |             default:
 | 
|---|
| 727 |                 if (c != ' ' && !isdigit(c)) {
 | 
|---|
| 728 |                     if (whynot)
 | 
|---|
| 729 |                         sprintf (whynot,"%s: B period suffix not Y, D or H: %c",
 | 
|---|
| 730 |                                                                 enm(flds), c);
 | 
|---|
| 731 |                     return (-1);
 | 
|---|
| 732 |                 }
 | 
|---|
| 733 |             }
 | 
|---|
| 734 | 
 | 
|---|
| 735 |         } else if (nsf==3 || nsf==6 || nsf==9) {
 | 
|---|
| 736 |             double yr;
 | 
|---|
| 737 |             int i;
 | 
|---|
| 738 | 
 | 
|---|
| 739 |             op->b_nbp = nsf/3;
 | 
|---|
| 740 |             for (i = 0; i < nsf; i += 3) {
 | 
|---|
| 741 |                 tmp = 0;
 | 
|---|
| 742 |                 crack_year (sflds[i+0], &tmp);
 | 
|---|
| 743 |                 mjd_year (tmp, &yr);
 | 
|---|
| 744 |                 op->b_bp[i/3].bp_ep = (float)yr;
 | 
|---|
| 745 |                 op->b_bp[i/3].bp_sep = atod(sflds[i+1]);
 | 
|---|
| 746 |                 op->b_bp[i/3].bp_pa = degrad(atod(sflds[i+2]));
 | 
|---|
| 747 |             }
 | 
|---|
| 748 |         } else {
 | 
|---|
| 749 |             if (whynot)
 | 
|---|
| 750 |                 sprintf (whynot,
 | 
|---|
| 751 |                        "%s: type B needs 3,6 or 7 subfields in field 7, not %d",
 | 
|---|
| 752 |                                                                 enm(flds), nsf);
 | 
|---|
| 753 |             return (-1);
 | 
|---|
| 754 |         }
 | 
|---|
| 755 | 
 | 
|---|
| 756 |         return (0);
 | 
|---|
| 757 | }
 | 
|---|
| 758 | 
 | 
|---|
| 759 | /* put all names in nm but load only the first into o_name */
 | 
|---|
| 760 | static int
 | 
|---|
| 761 | crack_name (Obj *op, char *flds[MAXFLDS], int nf, char nm[][MAXNM], int nnm)
 | 
|---|
| 762 | {
 | 
|---|
| 763 |         char *sflds[MAXFLDS];
 | 
|---|
| 764 |         int nsf;
 | 
|---|
| 765 |         int i;
 | 
|---|
| 766 |         
 | 
|---|
| 767 |         nsf = get_fields (flds[0], SUBFLD, sflds);
 | 
|---|
| 768 |         for (i = 0; nm && i < nsf && i < nnm; i++) {
 | 
|---|
| 769 |             strncpy (nm[i], sflds[i], MAXNM);
 | 
|---|
| 770 |             nm[i][MAXNM-1] = '\0';
 | 
|---|
| 771 |         }
 | 
|---|
| 772 |         strncpy (op->o_name, sflds[0], MAXNM-1);
 | 
|---|
| 773 |         return (nsf);
 | 
|---|
| 774 | }
 | 
|---|
| 775 | 
 | 
|---|
| 776 | /* simple name cracker just for error messages */
 | 
|---|
| 777 | static char *
 | 
|---|
| 778 | enm (char *flds[MAXFLDS])
 | 
|---|
| 779 | {
 | 
|---|
| 780 |         char *sflds[MAXFLDS];
 | 
|---|
| 781 |         int nsf = get_fields (flds[0], SUBFLD, sflds);
 | 
|---|
| 782 |         return (nsf > 0 ? sflds[0] : "Unknown");
 | 
|---|
| 783 | }
 | 
|---|
| 784 | 
 | 
|---|
| 785 | /* given either a decimal year (xxxx[.xxx]) or a calendar (x/x/x) date
 | 
|---|
| 786 |  * convert it to an mjd and store it at *p.
 | 
|---|
| 787 |  */
 | 
|---|
| 788 | static void
 | 
|---|
| 789 | crack_year (char *bp, double *p)
 | 
|---|
| 790 | {
 | 
|---|
| 791 |         int m, y;
 | 
|---|
| 792 |         double d;
 | 
|---|
| 793 | 
 | 
|---|
| 794 |         mjd_cal (*p, &m, &d, &y);       /* init with current */
 | 
|---|
| 795 |         f_sscandate (bp, PREF_MDY, &m, &d, &y);
 | 
|---|
| 796 |         cal_mjd (m, d, y, p);
 | 
|---|
| 797 | }
 | 
|---|
| 798 | 
 | 
|---|
| 799 | /* crack the startok and endok date fields found in several Obj types.
 | 
|---|
| 800 |  * set to 0 if blank or any problems.
 | 
|---|
| 801 |  */
 | 
|---|
| 802 | static void
 | 
|---|
| 803 | crack_okdates (char *fld, float *startok, float *endok)
 | 
|---|
| 804 | {
 | 
|---|
| 805 |         char *sflds[MAXFLDS];
 | 
|---|
| 806 |         double tmp;
 | 
|---|
| 807 |         int m, y;
 | 
|---|
| 808 |         double d;
 | 
|---|
| 809 |         int nsf;
 | 
|---|
| 810 | 
 | 
|---|
| 811 |         *startok = *endok = 0;
 | 
|---|
| 812 |         nsf = get_fields(fld, SUBFLD, sflds);
 | 
|---|
| 813 |         if (nsf > 1) {
 | 
|---|
| 814 |             d = m = y = 0;
 | 
|---|
| 815 |             f_sscandate (sflds[1], PREF_MDY, &m, &d, &y);
 | 
|---|
| 816 |             cal_mjd (m, d, y, &tmp);
 | 
|---|
| 817 |             *startok = (float)tmp;
 | 
|---|
| 818 |             if (nsf > 2) {
 | 
|---|
| 819 |                 d = m = y = 0;
 | 
|---|
| 820 |                 f_sscandate (sflds[2], PREF_MDY, &m, &d, &y);
 | 
|---|
| 821 |                 cal_mjd (m, d, y, &tmp);
 | 
|---|
| 822 |                 *endok = (float)tmp;
 | 
|---|
| 823 |             }
 | 
|---|
| 824 |         }
 | 
|---|
| 825 | }
 | 
|---|
| 826 | 
 | 
|---|
| 827 | /* add startok and endok to string at lp if non-zero.
 | 
|---|
| 828 |  * return number of characters added.
 | 
|---|
| 829 |  */
 | 
|---|
| 830 | static int
 | 
|---|
| 831 | get_okdates (char *lp, float *sp, float *ep)
 | 
|---|
| 832 | {
 | 
|---|
| 833 |         char *lp0 = lp;
 | 
|---|
| 834 | 
 | 
|---|
| 835 |         if (*sp || *ep) {
 | 
|---|
| 836 |             *lp++ = '|';
 | 
|---|
| 837 |             if (*sp)
 | 
|---|
| 838 |                 lp += fs_date (lp, *sp);
 | 
|---|
| 839 |             if (*ep) {
 | 
|---|
| 840 |                 *lp++ = '|';
 | 
|---|
| 841 |                 lp += fs_date (lp, *ep);
 | 
|---|
| 842 |             }
 | 
|---|
| 843 |         }
 | 
|---|
| 844 | 
 | 
|---|
| 845 |         return (lp - lp0);
 | 
|---|
| 846 | }
 | 
|---|
| 847 | 
 | 
|---|
| 848 | static void
 | 
|---|
| 849 | write_f (Obj *op, char lp[])
 | 
|---|
| 850 | {
 | 
|---|
| 851 |         double tmp;
 | 
|---|
| 852 | 
 | 
|---|
| 853 |         lp += sprintf (lp, "%s,f", op->o_name);
 | 
|---|
| 854 |         if (op->f_class)
 | 
|---|
| 855 |             lp += sprintf (lp, "|%c", op->f_class);
 | 
|---|
| 856 |         if (op->f_spect[0])
 | 
|---|
| 857 |             lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
 | 
|---|
| 858 |         *lp++ = ',';
 | 
|---|
| 859 |         lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
 | 
|---|
| 860 |         if (op->f_pmRA)
 | 
|---|
| 861 |             lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
 | 
|---|
| 862 |         *lp++ = ',';
 | 
|---|
| 863 |         lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
 | 
|---|
| 864 |         if (op->f_pmdec)
 | 
|---|
| 865 |             lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
 | 
|---|
| 866 |         lp += sprintf (lp, ",%.2f", get_mag(op));
 | 
|---|
| 867 |         mjd_year (op->f_epoch, &tmp);
 | 
|---|
| 868 |         lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
 | 
|---|
| 869 |         lp += sprintf (lp, ",%.7g", op->f_size);
 | 
|---|
| 870 |         if (op->f_size && (op->f_ratio || op->f_pa))
 | 
|---|
| 871 |             lp += sprintf (lp,"|%g|%g", op->f_size*get_ratio(op),
 | 
|---|
| 872 |                                                             raddeg(get_pa(op)));
 | 
|---|
| 873 | }
 | 
|---|
| 874 | 
 | 
|---|
| 875 | static void
 | 
|---|
| 876 | write_e (Obj *op, char lp[])
 | 
|---|
| 877 | {
 | 
|---|
| 878 |         lp += sprintf (lp, "%s,e", op->o_name);
 | 
|---|
| 879 |         lp += sprintf (lp, ",%.7g", op->e_inc);
 | 
|---|
| 880 |         lp += sprintf (lp, ",%.7g", op->e_Om);
 | 
|---|
| 881 |         lp += sprintf (lp, ",%.7g", op->e_om);
 | 
|---|
| 882 |         lp += sprintf (lp, ",%.7g", op->e_a);
 | 
|---|
| 883 |         lp += sprintf (lp, ",%.7g", 0.0);               /* retired op->e_n */
 | 
|---|
| 884 |         lp += sprintf (lp, ",%.7g", op->e_e);
 | 
|---|
| 885 |         lp += sprintf (lp, ",%.7g", op->e_M);
 | 
|---|
| 886 |         *lp++ = ',';
 | 
|---|
| 887 |         lp += fs_date (lp, op->e_cepoch);
 | 
|---|
| 888 |         lp += get_okdates (lp, &op->e_startok, &op->e_endok);
 | 
|---|
| 889 |         *lp++ = ',';
 | 
|---|
| 890 |         lp += fs_date (lp, op->e_epoch);
 | 
|---|
| 891 |         if (op->e_mag.whichm == MAG_gk)
 | 
|---|
| 892 |             lp += sprintf (lp, ",g%.7g", op->e_mag.m1);
 | 
|---|
| 893 |         else if (op->e_mag.whichm == MAG_HG)
 | 
|---|
| 894 |             lp += sprintf (lp, ",H%.7g", op->e_mag.m1);
 | 
|---|
| 895 |         else
 | 
|---|
| 896 |             lp += sprintf (lp, ",%.7g", op->e_mag.m1);
 | 
|---|
| 897 |         lp += sprintf (lp, ",%.7g", op->e_mag.m2);
 | 
|---|
| 898 |         lp += sprintf (lp, ",%.7g", op->e_size);
 | 
|---|
| 899 | }
 | 
|---|
| 900 | 
 | 
|---|
| 901 | static void
 | 
|---|
| 902 | write_h (Obj *op, char lp[])
 | 
|---|
| 903 | {
 | 
|---|
| 904 |         lp += sprintf (lp, "%s,h", op->o_name);
 | 
|---|
| 905 |         *lp++ = ',';
 | 
|---|
| 906 |         lp += fs_date (lp, op->h_ep);
 | 
|---|
| 907 |         lp += get_okdates (lp, &op->h_startok, &op->h_endok);
 | 
|---|
| 908 |         lp += sprintf (lp, ",%.7g", op->h_inc);
 | 
|---|
| 909 |         lp += sprintf (lp, ",%.7g", op->h_Om);
 | 
|---|
| 910 |         lp += sprintf (lp, ",%.7g", op->h_om);
 | 
|---|
| 911 |         lp += sprintf (lp, ",%.7g", op->h_e);
 | 
|---|
| 912 |         lp += sprintf (lp, ",%.7g", op->h_qp);
 | 
|---|
| 913 |         *lp++ = ',';
 | 
|---|
| 914 |         lp += fs_date (lp, op->h_epoch);
 | 
|---|
| 915 |         lp += sprintf (lp, ",%.7g", op->h_g);
 | 
|---|
| 916 |         lp += sprintf (lp, ",%.7g", op->h_k);
 | 
|---|
| 917 |         lp += sprintf (lp, ",%.7g", op->h_size);
 | 
|---|
| 918 | }
 | 
|---|
| 919 | 
 | 
|---|
| 920 | static void
 | 
|---|
| 921 | write_p (Obj *op, char lp[])
 | 
|---|
| 922 | {
 | 
|---|
| 923 |         lp += sprintf (lp, "%s,p", op->o_name);
 | 
|---|
| 924 |         *lp++ = ',';
 | 
|---|
| 925 |         lp += fs_date (lp, op->p_ep);
 | 
|---|
| 926 |         lp += get_okdates (lp, &op->p_startok, &op->p_endok);
 | 
|---|
| 927 |         lp += sprintf (lp, ",%.7g", op->p_inc);
 | 
|---|
| 928 |         lp += sprintf (lp, ",%.7g", op->p_om);
 | 
|---|
| 929 |         lp += sprintf (lp, ",%.7g", op->p_qp);
 | 
|---|
| 930 |         lp += sprintf (lp, ",%.7g", op->p_Om);
 | 
|---|
| 931 |         *lp++ = ',';
 | 
|---|
| 932 |         lp += fs_date (lp, op->p_epoch);
 | 
|---|
| 933 |         lp += sprintf (lp, ",%.7g", op->p_g);
 | 
|---|
| 934 |         lp += sprintf (lp, ",%.7g", op->p_k);
 | 
|---|
| 935 |         lp += sprintf (lp, ",%.7g", op->p_size);
 | 
|---|
| 936 | }
 | 
|---|
| 937 | 
 | 
|---|
| 938 | static void
 | 
|---|
| 939 | write_E (Obj *op, char lp[])
 | 
|---|
| 940 | {
 | 
|---|
| 941 |         lp += sprintf (lp, "%s,E", op->o_name);
 | 
|---|
| 942 |         *lp++ = ',';
 | 
|---|
| 943 |         lp += fs_date (lp, op->es_epoch);
 | 
|---|
| 944 |         lp += get_okdates (lp, &op->es_startok, &op->es_endok);
 | 
|---|
| 945 |         lp += sprintf (lp, ",%.7g", op->es_inc);
 | 
|---|
| 946 |         lp += sprintf (lp, ",%.7g", op->es_raan);
 | 
|---|
| 947 |         lp += sprintf (lp, ",%.7g", op->es_e);
 | 
|---|
| 948 |         lp += sprintf (lp, ",%.7g", op->es_ap);
 | 
|---|
| 949 |         lp += sprintf (lp, ",%.7g", op->es_M);
 | 
|---|
| 950 |         lp += sprintf (lp, ",%.7g", op->es_n);
 | 
|---|
| 951 |         lp += sprintf (lp, ",%.7g", op->es_decay);
 | 
|---|
| 952 |         lp += sprintf (lp, ",%d", op->es_orbit);
 | 
|---|
| 953 |         lp += sprintf (lp, ",%.7g", op->es_drag);
 | 
|---|
| 954 | }
 | 
|---|
| 955 | 
 | 
|---|
| 956 | static void
 | 
|---|
| 957 | write_B (Obj *op, char lp[])
 | 
|---|
| 958 | {
 | 
|---|
| 959 |         double tmp;
 | 
|---|
| 960 | 
 | 
|---|
| 961 |         lp += sprintf (lp, "%s,B", op->o_name);
 | 
|---|
| 962 |         if (op->f_class)
 | 
|---|
| 963 |             lp += sprintf (lp, "|%c", op->f_class);
 | 
|---|
| 964 |         if (op->f_spect[0])
 | 
|---|
| 965 |             lp += sprintf (lp, "|%.*s", (int)sizeof(op->f_spect), op->f_spect);
 | 
|---|
| 966 |         if (op->b_2spect[0])
 | 
|---|
| 967 |             lp += sprintf (lp, "|%.*s", (int)sizeof(op->b_2spect),op->b_2spect);
 | 
|---|
| 968 |         *lp++ = ',';
 | 
|---|
| 969 |         lp += fs_sexa (lp, radhr(op->f_RA), 2, 36000);
 | 
|---|
| 970 |         if (op->f_pmRA)
 | 
|---|
| 971 |             lp += sprintf (lp, "|%.6g",cos(op->f_dec)*op->f_pmRA/1.327e-11);
 | 
|---|
| 972 |         *lp++ = ',';
 | 
|---|
| 973 |         lp += fs_sexa (lp, raddeg(op->f_dec), 3, 3600);
 | 
|---|
| 974 |         if (op->f_pmdec)
 | 
|---|
| 975 |             lp += sprintf (lp, "|%.6g", op->f_pmdec/1.327e-11);
 | 
|---|
| 976 |         lp += sprintf (lp, ",%.2f", get_mag(op));
 | 
|---|
| 977 |         lp += sprintf (lp, "|%.2f", op->b_2mag/MAGSCALE);
 | 
|---|
| 978 |         mjd_year (op->f_epoch, &tmp);
 | 
|---|
| 979 |         lp += sprintf (lp, ",%.6g", tmp); /* %.7g gives 2000.001 */
 | 
|---|
| 980 |         if (op->b_nbp == 0) {
 | 
|---|
| 981 |             lp += sprintf (lp, ",%.6g",  op->b_bo.bo_a);
 | 
|---|
| 982 |             lp += sprintf (lp, "|%.6g",  op->b_bo.bo_i);
 | 
|---|
| 983 |             lp += sprintf (lp, "|%.6g",  op->b_bo.bo_O);
 | 
|---|
| 984 |             lp += sprintf (lp, "|%.6g",  op->b_bo.bo_e);
 | 
|---|
| 985 |             lp += sprintf (lp, "|%.6g",  op->b_bo.bo_T);
 | 
|---|
| 986 |             lp += sprintf (lp, "|%.6g",  op->b_bo.bo_o);
 | 
|---|
| 987 |             lp += sprintf (lp, "|%.6gy", op->b_bo.bo_P);
 | 
|---|
| 988 |         } else {
 | 
|---|
| 989 |             int i;
 | 
|---|
| 990 | 
 | 
|---|
| 991 |             for (i = 0; i < op->b_nbp; i++) {
 | 
|---|
| 992 |                 BinPos *bp = &op->b_bp[i];
 | 
|---|
| 993 |                 lp += sprintf (lp, "%c%.6g", i==0?',':'|', bp->bp_ep);
 | 
|---|
| 994 |                 lp += sprintf (lp, "|%.6g", bp->bp_sep);
 | 
|---|
| 995 |                 lp += sprintf (lp, "|%.6g", raddeg(bp->bp_pa));
 | 
|---|
| 996 |             }
 | 
|---|
| 997 |         }
 | 
|---|
| 998 | }
 | 
|---|
| 999 | 
 | 
|---|
| 1000 | static void
 | 
|---|
| 1001 | write_P (Obj *op, char lp[])
 | 
|---|
| 1002 | {
 | 
|---|
| 1003 | 
 | 
|---|
| 1004 |         lp += sprintf (lp, "%s,P", op->o_name);
 | 
|---|
| 1005 | }
 | 
|---|
| 1006 | 
 | 
|---|
| 1007 | /* For RCS Only -- Do Not Edit */
 | 
|---|
| 1008 | static char *rcsid[2] = {(char *)rcsid, "@(#) $RCSfile: dbfmt.c,v $ $Date: 2005-03-07 16:47:17 $ $Revision: 1.5 $ $Name: not supported by cvs2svn $"};
 | 
|---|